SpringBoot 백 엔 드 데이터 검증 JSR 303 사용 상세 설명
20016 단어 SpringBoot데이터 검사JSR303쓰다
간단 한 소개
앞 뒤 에서 데이터 인 터 랙 션 을 하 는 과정 에서 전단 에서 데 이 터 를 백 엔 드 로 전송 하기 전에 보통 한 번 검 사 를 하고 검사 가 성공 한 후에 야 데 이 터 를 백 엔 드 로 보 냅 니 다.그러나 우 리 는 서버 에서 데 이 터 를 한 번 더 검증 해 야 한다.요청 한 데 이 터 를 보 내 는 링크 는 쉽게 얻 을 수 있 기 때문에 전단 인터페이스 를 거치 지 않 고 postman 등 도 구 를 사용 하여 배경 에 데 이 터 를 직접 보 낼 수 있 기 때문에 보 낸 데 이 터 는 비합법적 인 상황 이 될 수 있 습 니 다.
프로젝트 생 성
우선 springboot 프로젝트 를 만 듭 니 다.
사용 하 는 spring boot 버 전 은 다음 과 같 습 니 다.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
다음 의존 도입
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
이 표 지 는 새로운 spring boot 버 전에 서 단독으로 도입 해 야 합 니 다.이전 버 전에 서 는 기본적으로 도입 되 었 다.이것 은 jsr 303 주해 에 대한 지원 을 도입 하 는 데 쓰 인 다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
그리고 자바 빈 을 만 듭 니 다.
package cn.jxj4869.demo.entity;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class User {
@NotNull
private Integer id;
private String username;
private String password;
private String email;
}
형식의 자바 빈 을 되 돌려 줍 니 다.
package cn.jxj4869.demo.entity;
import java.util.HashMap;
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("code", 0);
put("msg", "success");
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
controller 를 만 듭 니 다.index 방법 은 첫 페이지 로 넘 어 가 는 데 사 용 됩 니 다.
package cn.jxj4869.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class UserController {
@RequestMapping("/")
public String index(){
return "index";
}
}
홈 페이지 코드 는resources/templates
디 렉 터 리 아래 에 놓 습 니 다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
margin-top: 50px;
}
</style>
</head>
<body>
<div>
<br><br>
<form method="post">
<label> </label>
<input type="text" name="username"/>
<br>
<label> </label>
<input type="text" name="password"/>
<br>
<label> </label>
<input type="email" name="email"/>
<br>
<input type="submit" value=" "/>
</form>
</div>
<div>
<br><br>
<form method="post">
<input type="hidden" name="id" value="1">
<label> </label>
<input type="text" name="username"/>
<br>
<label> </label>
<input type="text" name="password"/>
<br>
<label> </label>
<input type="email" name="email"/>
<br>
<input type="submit" value=" "/>
</form>
</div>
</body>
</html>
전통 적 인 검증 방식백 엔 드 에서 데이터 검 사 를 하려 면 전통 적 인 검사 방식 은 controller 층 에서 데 이 터 를 받 은 후에 요구 에 따라 데 이 터 를 검사 합 니 다.
예 를 들 어 user bean 대상 을 받 아야 합 니 다.
현재 user 대상 의
username
속성 을 비공 식 검사 하고password
속성 을 비공 식 검사 하고 길이 검 사 를 해 야 합 니 다.
@PostMapping("/user")
@ResponseBody
public R user1(User user) throws Exception {
if(StringUtils.isEmpty(user.getUsername())) {
return R.error(400,"username ");
}
if(StringUtils.isEmpty(user.getPassword())||user.getPassword().length()>8||user.getPassword().length() <4) {
return R.error(400,"password ");
}
return null;
}
만약 에 여러 가지 방법 이 user 대상 을 받 아들 여야 하고 검증 해 야 하 는 속성 이username
과password
두 가지 속성 에 그 치지 않 을 수 있 습 니 다.만약 에 모든 방법 에서 위 와 같은 검증 방식 을 사용 하면 코드 가 비대 하고 유지 하기 어 려 울 수 있 습 니 다.userbean 의 속성 을 바 꾸 거나 검증 규칙 을 수정 한 후에모든 검사 코드 를 업데이트 해 야 합 니 다.이것 은 공 사 량 이 매우 많은 일이 다.JSR 303 사용 하기
상술 한 문 제 를 해결 하기 위해 서,우 리 는 JSR 303 이 제공 한 주 해 를 사용 하여 검사 할 수 있다.
JSR 은 자바 Specification Requests 의 줄 임 말로 자바 규범 제안 을 의미한다.JSR 303,즉 303 호 제안 입 니 다.
JSR 303 을 사용 하 는 방법 은 매우 간단 합 니 다.예 를 들 어 위의 수요,우 리 는 user 의 속성 에 주 해 를 추가 하면 됩 니 다.
절 차 는 다음 과 같다.
1.빈 에 게 검사 주 해 를 추가 합 니 다.보통
javax.validation.constraints
이 가방 에서 도 일부hibernate
가 제공 합 니 다.2.검증 기능@Valid 를 엽 니 다.
3.검사 에 실 패 했 을 때
org.springframework.validation.BindException
이상 을 던 집 니 다.자주 사용 하 는 검사 주 해 는 문장 끝 에 있다.
package cn.jxj4869.demo.entity;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
@Data
public class User {
private Integer id;
@NotBlank
private String username;
@NotBlank
@Length(min = 4,max = 8)
private String password;
private String email;
}
그리고 controller 안의 방법 에@Valid
주 해 를 더 하면 됩 니 다.
@PostMapping("/user2")
@ResponseBody
public R user2(@Valid User user) throws Exception {
System.out.println(user);
return null;
}
검사 에 실패 하면 다음 과 같은 오류 가 발생 합 니 다.기본 알림 메 시 지 를 드 립 니 다.사용자 정의 오류 정보
그럼 이 잘못된 메 시 지 는 어떻게 된 거 예요?
@NotNULL
주석 코드 에 들 어가 기
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { })
public @interface NotBlank {
String message() default "{javax.validation.constraints.NotNull.message}";
............
............
............
}
속성 이 하나message
있 습 니 다.잘못된 힌트 내용 을 지정 한 것 이 분명 하 다.이 오류 알림 은validationMessages.properties
라 는 파일 에서 아이디어 검색 도 구 를 사용 하여 찾 을 수 있 습 니 다.shift
키 를 더 블 클릭 하여 검색 을 엽 니 다.이렇게 많은
validationMessages.properties
문서 가 있 고 국제 화 를 지원 하 는 것 을 발견 했다.validationMessages_zh.properties
을 열 면 이렇게 많은 힌트 를 정의 하 는 것 을 볼 수 있 습 니 다.오류 알림 은 이 파일 에서 가 져 온 것 입 니 다.기본 검사 알림 정 보 를 사용 하지 않 으 려 면 스스로 지정 할 수 있 습 니 다.
message 의 값 을 지정 하면 됩 니 다.
@NotBlank(message = " ")
private String username;
오류 정보 가 져 오기 및 응답
검사 가 잘못 되 었 을 때 오류 인 터 페 이 스 를 기본적으로 되 돌려 주거 나 오류 알림 의 json 데 이 터 를 되 돌려 줍 니 다.그러나 기본적으로 제공 하 는 것 은 우리 가 원 하 는 것 이 아니 라 잘못된 정 보 를 얻 을 수 있다 면 해당 데 이 터 를 사용자 정의 할 수 있 습 니 다.
잘못된 정 보 를 얻 는 방식 도 간단 하 다.방법 에
BindingResult result
이라는 인 자 를 추가 하면 잘못된 정 보 는 이 안에 포 함 될 것 이다.
@PostMapping("/user2")
@ResponseBody
public R user2(@Valid User user, BindingResult result) throws Exception {
System.out.println(user);
if(result.hasErrors()) { //
Map<String,String> map = new HashMap<>();
//1、
result.getFieldErrors().forEach((item)->{
//FieldError
String message = item.getDefaultMessage();
//
String field = item.getField();
map.put(field,message);
});
return R.error(400," ").put("data",map);
}
// , 。
return null;
}
그러나 위의 이런 방식 을 추천 하지 않 습 니 다.이 유 는 똑 같 습 니 다.검사 할 곳 이 많아 졌 습 니 다.모든 방법 에 이런 이상 처 리 를 더 하면 코드 가 비대 해 집 니 다.springmvc 에 전역 적 인 이상 처리 가 있다 는 것 을 기억 하 시 는 지 모 르 겠 습 니 다.우 리 는 이상 처 리 를 사용자 정의 하여 이 안에서 이상 처 리 를 통일 할 수 있 습 니 다.
통일 처리
BinException
.이렇게 하면 controller 에서 잘못된 정 보 를 처리 하지 않 아 도 된다.
package cn.jxj4869.demo.execption;
import cn.jxj4869.demo.entity.R;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice(basePackages = "cn.jxj4869.demo.controller")
public class MyExceptionControllerAdvice {
@ExceptionHandler(value = BindException.class)
public R handleVaildException(BindException e) {
Map<String,String> map = new HashMap<>();
//1、
e.getFieldErrors().forEach((item)->{
//FieldError
String message = item.getDefaultMessage();
//
String field = item.getField();
map.put(field,message);
});
return R.error(400," ").put("data",map);
}
}
오류 이상 유형 보충오 류 를 검사 할 때 두 가지 이상 을 던 집 니 다.
org.springframework.validation.BindException
@Valid
주 해 를 사용 하여 검사 할 때 던 진 것 입 니 다.org.springframework.web.bind.MethodArgumentNotValidException
사용@validated
검사 할 때 던 진 것이상 포획 에 아래 이 걸 넣 으 세 요.
@ExceptionHandler(value= MethodArgumentNotValidException.class)
public R handleVaildException(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
Map<String,String> map = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError)->{
map.put(fieldError.getField(),fieldError.getDefaultMessage());
});
return R.error(400," ").put("data",map);
}
그룹 검사서로 다른 업무 장면 에서 검사 규칙 은 다르다.예 를 들 어 user 대상
id
이라는 속성 은 새로 추 가 될 때 이 속성 은 채 우지 않 고 null 이 어야 하지만 수정 할 때id
속성 은 null 이 될 수 없다.주해 중의
groups
속성 으로 지정 할 수 있 으 며,어떤 상황 에서 개 주 해 를 사용 할 수 있 습 니까?
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
public @interface NotBlank {
Class<?>[] groups() default { };
........
}
먼저 두 개의 인터페이스AddGroup
와UpdateGroup
를 정의 하고 그 어떠한 실현 도 할 필요 가 없다.
package cn.jxj4869.demo.valid;
public interface UpdateGroup {
}
package cn.jxj4869.demo.valid;
public interface AddGroup {
}
user 에 group 을 지정 합 니 다.
package cn.jxj4869.demo.entity;
import cn.jxj4869.demo.valid.AddGroup;
import cn.jxj4869.demo.valid.UpdateGroup;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
@Data
public class User {
@Null(groups = {AddGroup.class})
@NotNull(groups = {UpdateGroup.class})
private Integer id;
@NotBlank(message = " ",groups = {AddGroup.class,UpdateGroup.class})
private String username;
@NotEmpty
private String password;
private String email;
}
controller 에서@Validated
주석 을 사용 하여 검사 할 그룹 을 지정 합 니 다.
@PostMapping("/user3")
@ResponseBody
public R user3(@Validated(UpdateGroup.class) User user) {
System.out.println(user);
return null;
}
결 과 는 다음 그림 에서 보 듯 이password
속성 이 검사 할 그룹 을 지정 하지 않 았 기 때문에 검사 할 때 합 법성 검 사 를 하지 않 습 니 다.사용자 정의 검사
제 공 된 주해 가 우리 의 요 구 를 만족 시 키 지 못 할 때 주 해 를 사용자 정의 할 수 있 습 니 다.
예 를 들 어 우 리 는 현재 user 에 속성
status
을 추가 하고 이 속성의 값 은 0 또는 1 만 요구 합 니 다.새 주석
@StatusValue
을 만 듭 니 다.jsr 303 의 규범 에 따라 주 해 를 검사 하 는 데 세 가지 속성 이 있다.
message
:잘못된 힌트 를 얻 기 위 한groups
:검사 그룹 을 지정 합 니 다.@Constraint
주 해 를 사용 하여 이 주 해 를 지정 하 는 검사 기 를 사용 합 니 다.
package cn.jxj4869.demo.valid;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
@Constraint(validatedBy = { StatusValueConstraintValidator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@interface StatusValue {
String message() default "{cn.jxj4869.valid.StatusValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] value() default { };
}
사용자 정의 검사 기이 인 터 페 이 스 를 실현 해 야 합 니 다
ConstraintValidator
.첫 번 째 범 형 은 어떤 주 해 를 검사 해 야 하 는 지,두 번 째 범 형 은 검사 해 야 할 데이터 의 유형 입 니 다.initialize
초기 화 방법isValid
검사 방법,검사 성공 여 부 를 판단
package cn.jxj4869.demo.valid;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
public class StatusValueConstraintValidator implements ConstraintValidator<StatusValue,Integer> {
private Set<Integer> set = new HashSet<>();
//
@Override
public void initialize(StatusValue constraintAnnotation) {
int[] value = constraintAnnotation.value();
for (int val : value) {
set.add(val);
}
}
/**
*
* @param value
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
마지막 으로resources
디 렉 터 리 에ValidationMessages.properties
파일 을 추가 합 니 다.오류 정 보 를 지정 하 는 데 사용 합 니 다.
cn.jxj4869.valid.StatusValue.message=
UserBean
@Data
public class User {
@Null(groups = {AddGroup.class})
@NotNull(groups = {UpdateGroup.class})
private Integer id;
@NotBlank(message = " ",groups = {AddGroup.class,UpdateGroup.class})
private String username;
@NotEmpty
private String password;
private String email;
@StatusValue(value = {0,1},groups = {AddGroup.class,UpdateGroup.class})
private Integer status;
}
상용 주해 집합
주해
기능.
@Null
대상 은 null 이 어야 합 니 다.
@NotNull
대상 이 null 이 아니 어야 합 니 다.길이 가 0 인 문자열 을 검사 할 수 없습니다.
@NotBlank
문자열 은 Null 이 아니 라 앞 뒤 공백 길 이 를 0 이상 제거 해 야 합 니 다.
@NotEmpty
문자열 이 비어 있어 야 합 니 다.
@Length(min = 1,max = 50)
문자열 은 지정 한 길이 안에 있어 야 합 니 다.
@Range(min = 0,max = 100)
지 정 된 범위 내 에서
@AssertTrue
대상 은 true 여야 합 니 다.
@AssertFalse
대상 은 false 여야 합 니 다.
@Max(Value)
숫자 여야 하 며,Value 보다 작 거나 같 아야 합 니 다.
@Min(Value)
숫자 여야 하 며,Value 보다 크 거나 같 아야 합 니 다.
@DecimalMax(Value)
숫자(BigDecimal)이 어야 하 며,Value 보다 작 거나 같 아야 합 니 다.소수 존재 정밀도
@DecimalMin(Value)
숫자(BigDecimal)이 어야 하 며,Value 보다 크 거나 같 아야 합 니 다.소수 존재 정밀도
@Digits(integer,fraction)
숫자(BigDecimal),integer 정수 정밀도,fraction 소수 정밀도 여야 합 니 다.
@Size(min,max)
대상(Array,Collection,Map,String)길 이 는 주어진 범위 에 있어 야 합 니 다.
문자열 은 합 법 적 인 메 일 주소 여야 합 니 다.
@Past
Date 와 Calendar 대상 은 현재 시간 전에
@Future
Date 와 Calendar 대상 은 현재 시간 이후 에
@Pattern(regexp="정규")
문자열 이 정규 표현 식 의 값 을 만족 시 킵 니 다.
여기 서 SpringBoot 백 엔 드 에서 데이터 검증 JSR 303 의 사용 에 대한 상세 한 설명 을 소개 합 니 다.더 많은 SpringBoot 데이터 검증 JSR 303 의 사용 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.