@Valid와 @Validated, Errors

kkily·2024년 5월 17일
0

Spring

목록 보기
3/3
post-thumbnail

@Valid

@Valid란 빈 검증기(Bean Validator)를 이용해 객체의 제약 조건을 검증하도록 지시하는 어노테이션이다.

다음의 의존성을 build.gradle에 추가해줘야 한다!

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'

예시

@Getter
@Setter
public class MemberDTO {

  @NotBlank
  @JsonProperty("user_id")
  private String userId;
  @NotBlank
  @Pattern(regexp="(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,20}",
      message = "비밀번호는 영문 대,소문자와 숫자, 특수기호가 적어도 1개 이상씩 포함된 8자 ~ 20자의 비밀번호여야 합니다.")
  private String pw;
  @NotBlank
  private String name;
  @Email
  private String email;
  @NotBlank
  private String contact;

  public Member convertToEntity(){
    return new Member(userId,pw,name,email,contact);
  }

}

그리고 다음과 같이 컨트롤러의 메소드에 @Valid를 붙여주면 유효성 검증이 진행된다.

  @PostMapping("/join/api/result") // After
  public ApiUtils.ApiResult<String> joinByApiResult(@Valid @RequestBody MemberDTO memberDTO,
      Errors errors) {
...
}

다양한 제약조건 annotation

@NotNull: 해당 값이 null이 아닌지 검증함
@NotEmpty: 해당 값이 null이 아니고, 빈 스트링("") 아닌지 검증함(" "은 허용됨)
@NotBlank: 해당 값이 null이 아니고, 공백(""과 " " 모두 포함)이 아닌지 검증함
@AssertTrue: 해당 값이 true인지 검증함
@Size: 해당 값이 주어진 값 사이에 해당하는지 검증함(String, Collection, Map, Array에도 적용 가능)
@Min: 해당 값이 주어진 값보다 작지 않은지 검증함
@Max: 해당 값이 주어진 값보다 크지 않은지 검증함
@Pattern: 해당 값이 주어진 패턴과 일치하는지 검증함

@Validated

입력 파라미터의 유효성 검증은 컨트롤러에서 최대한 처리하고 넘겨주는 것이 좋다. 하지만 개발을 하다보면 불가피하게 다른 곳에서 파라미터를 검증해야 할 수 있다. Spring에서는 이를 위해 AOP 기반으로 메소드의 요청을 가로채서 유효성 검증을 진행해주는 @Validated를 제공하고 있다.

클래스에 @Validated를 붙여주고, 유효성을 검증할 메소드의 파라미터에 @Valid를 붙여주면 유효성 검증이 진행된다.

@Service
@Validated
public class MemberService {

	public void addMember(@Valid AddMemberRequest addMemberRequest) {
		...
	}
}

errors

@Valid에 의해 발생한 Validation Error는 기본적으로 Errors 인터페이스 타입의 객체에 담긴다.

따라서 메서드의 인자로 Errors 타입의 객체를 받는지 or 안받는지에 따라 처리가 달라진다.

상황1) Errors 타입 객체를 포함하지 않았을 때 (400 Bad Request 자동 반환)

@PostMapping("/user/sign-up")
public ResponseEntity<SingleResult<UserDto.UserSignUpResDto>> userSignUp(
            @RequestBody @Valid UserDto.UserSignUpReqDto userSignUpReqDto) {
				...
}

상황2) Errors 타입 객체를 포함했을 때 (if문으로 추가 처리해줘야 함)

@PostMapping("/user/sign-up")
public ResponseEntity<SingleResult<UserDto.UserSignUpResDto>> userSignUp(
            @RequestBody @Valid UserDto.UserSignUpReqDto userSignUpReqDto, Errors errors) {
				...
	if (errors.hasErrors()) { ... }
    			...
}

나는 Errors 타입 객체를 포함해서 if문으로 추가 처리를 해줬다.

@PostMapping("/join/api/result") // After
  public ApiUtils.ApiResult<String> joinByApiResult(@Valid @RequestBody MemberDTO memberDTO,
      Errors errors) {
    if (errors.hasErrors()) {
      return error("유효성 에러!",HttpStatus.BAD_REQUEST);
    }
	...
}

참고 블로그
참고 블로그2

profile
낄리의 개발 블로그╰(*°▽°*)╯

0개의 댓글

관련 채용 정보