Spring Boot는 매개변수 검증의 기본 사용을 실현합니다.


Java API 사양(JSR303) 의 간단한 사용은 Bean 유효성 검사를 위한 표준 validation-api를 정의하지만 구현을 제공하지는 않습니다. 최대 절전 모드 유효성 검사는 이 사양의 구현이며 @Email, @Length 등과 같은 유효성 검사 주석을 추가합니다. Spring Validation은 최대 절전 모드 유효성 검사의 2차 캡슐화로, Spring mvc 매개변수의 자동 유효성 검사를 지원하는 데 사용됩니다. 다음으로 Spring Validation의 사용을 소개하기 위해 spring-boot 프로젝트를 예로 들어 보겠습니다.

종속성 소개
spring-boot 버전이 2.3.x 미만인 경우 spring-boot-starter-web은 자동으로 hibernate-validator 종속성을 가져옵니다. 스프링 부트 버전이 2.3.x보다 크면 종속성을 수동으로 도입해야 합니다.

<!--JSR303 데이터 검증-->
<종속성>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
   <version>2.6.4</version>
< /의존성>
웹 서비스의 경우 불법적인 매개변수가 비즈니스에 영향을 미치지 않도록 컨트롤러 계층에서 매개변수 검증이 이루어져야 합니다! 대부분의 경우 요청 매개변수는 다음 두 가지 형식으로 나뉩니다.

POST 및 PUT 요청의 경우 requestBody를 사용하여 매개변수를 전달하십시오.

GET 요청, requestParam/PathVariable을 사용하여 매개변수를 전달합니다.

requestBody 및 requestParam/PathVariable의 실제 매개변수 검증에 대해 간단히 소개하겠습니다!

requestBody 매개변수 확인
POST 및 PUT 요청은 일반적으로 requestBody를 사용하여 매개변수를 전달합니다. 이 경우 백엔드는 DTO 개체를 사용하여 수신합니다. @Validated 주석을 DTO 개체에 추가하기만 하면 자동 매개 변수 유효성 검사가 수행됩니다. 예를 들어, userName의 길이가 2-10이고 암호 필드의 길이가 6-20이어야 하는 User를 저장하기 위한 인터페이스가 있습니다. 확인이 실패하면 MethodArgumentNotValidException이 발생하고 Spring은 기본적으로 이를 400(잘못된 요청) 요청으로 변환합니다.

DTO 필드에 제약 조건 주석 선언

@Data  
public class UserDTO {  
  
    private Long userId;  
  
    @NotNull  
    @Length(min = 2, max = 10)  
    private String userName;  
  
    @NotNull  
    @Length(min = 6, max = 20)  
    private String password;  
}  
메서드 매개변수 유효성 검사에서 선언 노트

@PostMapping("/save")  
public Result saveUser(@RequestBody @Validated UserDTO userDTO) {  
  
    return Result.ok();  
}  
이 경우 @Valid와 @Validated를 모두 사용할 수 있습니다.

requestParam/PathVariable 매개변수 확인
GET 요청은 일반적으로 requestParam/PathVariable을 사용하여 매개변수를 전달합니다. 이 경우 Controller 클래스에 @Validated 주석을 표시하고 입력 매개변수에 제약 조건 주석(예: @Min 등)을 선언해야 합니다. 확인에 실패하면 ConstraintViolationException이 발생합니다. 코드 예제는 다음과 같습니다.

@RequestMapping("/api/user")  
@RestController  
@Validated  
public class UserController {  
  
    @GetMapping("{userId}")  
    public Result detail(@PathVariable("userId") @Min(10000000000000000L) Long userId) {  
  
        UserDTO userDTO = 새로운 UserDTO();  
        userDTO.setUserId(userId);   
        userDTO.setUserName("샤오샤오");   
        return Result.ok(userDTO);  
    }  
  
    @GetMapping("getByAccount")  
    공개 결과 getByAccount(@Length(min = 2, max = 10) @NotNull String username) {  
  
        UserDTO userDTO = new UserDTO();  
        userDTO.setUserId(10000000000000003L);  
        userDTO.   
        return Result.ok(userDTO);  
    }  
}  
통합된 예외 처리
확인에 실패하면 MethodArgumentNotValidException 또는 ConstraintViolationException이 발생합니다. 실제 프로젝트 개발에서 통합된 예외 처리는 일반적으로 보다 친숙한 프롬프트를 반환하는 데 사용됩니다. 예를 들어, 우리 시스템은 어떤 예외가 전송되더라도 http 상태 코드는 200을 반환해야 하며 비즈니스 코드는 시스템의 비정상적인 상황을 구별하는 데 사용됩니다.

@RestControllerAdvice  
공개 클래스 CommonExceptionHandler {  
  
    @ExceptionHandler({MethodArgumentNotValidException.class})  
    @ResponseStatus(HttpStatus.OK)  
    @ResponseBody  
    공개 결과 handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {  
        BindingResult bindingResult = ex.getBindingResult();  
        StringBuilder sb = new StringBuilder("校验失败:");  
        for (FieldError fieldError : bindingResult.getFieldErrors()) {  
            sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");  
        }  
        문자열 메시지 = sb.toString();  
       return Result.fail(msg);  

  
    @ExceptionHandler({ConstraintViolationException.class})   @ResponseStatus     ;           (ex.getMessage())  Result.fail return       public Result handleConstraintViolationException(ConstraintViolationException ex) {       @ResponseBody  
    (HttpStatus.OK)  이때 DTO 클래스의 필드에 제약 조건 주석을 추가하는 것만으로는 이 문제를 해결할 수 없습니다. 따라서 spring-validation은 이러한 문제를 해결하기 위해 특별히 사용되는 그룹 검증 기능을 지원합니다. 예를 들어 여전히 위의 예에서 User를 저장할 때 UserId는 비어 있을 수 있지만 User를 업데이트할 때 UserId의 값은 >=10000000000000000L이어야 합니다. 다른 필드에 대한 확인 규칙은 두 경우 모두 동일합니다. 이때 그룹 인증을 사용하는 코드 예시는 다음과 같습니다.






적용 가능한 그룹화 정보 그룹은 제약 조건 주석에 선언됩니다.

@Data  
public class UserDTO {  
 
    // 제한 업데이트(Update.class)  
    @Min(value = 10000000000000000L, groups = Update.class)  
    private Long userId;  
  
    // null이 아님, 길이 제한은 저장 및 업데이트 모두에 유효함
    @NotNull ( groups = {Save.class, Update.class})  
    @Length(min = 2, max = 10, groups = {Save.class, Update.class})  
    private String userName;  
  
    @NotNull(groups = {Save.class, Update .class})  
    @Length(min = 6, max = 20, groups = {Save.class, Update.class})  
    private String password;  
  
}  
@Validated 주석에 검증 그룹 지정

@PostMapping("/save")  
공개 결과 saveUser(@RequestBody @Validated(UserDTO.Save.class) UserDTO userDTO) {  
  
    return Result.ok();  
}  
  
@PostMapping("/update")  
공개 결과 updateUser(@RequestBody @ Validated(UserDTO.Update.class) UserDTO userDTO) {  
  
    return Result.ok();  
}  
중첩된 유효성 검사 
이전 예에서 DTO 클래스의 필드는 모두 기본 데이터 유형과 문자열 유형입니다. 그러나 실제 시나리오에서는 특정 필드가 개체이기도 할 수 있으며 이 경우 중첩 유효성 검사를 사용할 수 있습니다.

예를 들어 위에서 사용자 정보를 저장하면 주소 정보도 포함됩니다. 이때 DTO 클래스의 해당 필드는 @Valid 어노테이션으로 표시되어야 함을 유의해야 한다.

@Data  
public class UserDTO {  
  
    @Min(value = 10000000000000000L, groups = Update.class)  
    private Long userId;  
  
    @NotNull(groups = {Save.class, Update.class})  
    @Length(min = 2, max = 10, groups = {Save.class, Update.class})  
    private String userName;  
  
    @NotNull(groups = {Save.class, Update.class})  
    @Length(min = 6, max = 20, groups = {Save.class, Update.class})  
    private 문자열 암호;  
  
    @NotNull(groups = {Save.class, Update.class})  
    @유효한  
    개인 주소 추가;  
  
    @Data  
    공개 정적 클래스 주소{  
  
        @Min(값 = 1, 그룹 = Update.class)  
        private Long addrId;  
  
        @NotNull(groups = {Save.class, Update.class})  
        @Length(min = 2, max = 10, groups = {Save.class, Update.class})  
        private String addrName;  
  
        @NotNull(groups = {Save.class, Update.class})  
        @Length(min = 2, max = 10, groups = {Save.class, Update.class})  
        private String location;  
    }  
}   요청 본문이 컬렉션을 직접 전달하는 경우
컬렉션 유효성 검사 
백그라운드에서 컬렉션의 각 항목에 대해 매개변수 확인을 수행하기를 바랍니다. 이때 java.util.Collection 아래에 있는 목록이나 설정을 직접 사용하여 데이터를 수신하면 매개변수 검증이 적용되지 않습니다! 사용자 지정 목록 컬렉션을 사용하여 매개 변수를 받을 수 있습니다.

컬렉션 확인은 컬렉션의 각 항목을 확인합니다. 예를 들어 List<Address> 필드는 목록의 각 주소 개체를 확인합니다.

사용자 지정 목록 컬렉션
public class ValidationList<E> implements List<E> {  
  
    @Delegate  
    @Valid  
    public List<E> list = new ArrayList<>();  
  
    @Override  
    public String toString() {  
        return list.toString();  
    }  
}  
@Delegate 주석은 롬복 버전에 의해 제한되며 1.18.6 이상의 버전에서 지원됩니다. 확인에 실패하면 NotReadablePropertyException이 발생하며 통합 예외로도 처리할 수 있습니다.

한 번의 요청으로 여러 사용자 개체 저장

@PostMapping("/saveList")  
공개 결과 saveList(@RequestBody @Validated(UserDTO.Save.class) ValidationList<UserDTO> userList) {  
  
    return Result.ok();  
}  
@Valid和@Validated区别

おすすめ

転載: blog.csdn.net/qq_36647209/article/details/130184397