[해결하기] @Validated 사용하여 순서 정하기

이호인·2022년 7월 1일
0

📌 무엇을 해결하려했나요

회원가입 시 유효성 검증을 위해 @Valid 어노테이션을 사용하여 객체 단에서 유효성 검증을 하도록 했다. 설정해둔 @NotNull, @Size, @Pattern 등 조건에 부합하지 못하면 MethodArgumentNotValidException이 발생하고 이것을 커스텀해서 해당 메세지를 400에러와 함께 body에 넣어 클라이언트 쪽으로 보내도록 했다.

이때 에러 메세지가 무작위로 변경되어 나타났는데, 내가 원하는 것은

@NotNull ---> @Size ---> @Pattern 이런 식으로 메세지를 내려주길 원했다.

  • 아무것도 입력하지 않은 것은 동일하지만 가입 버튼을 누를 때마다 다른 메세지가 뜬다.
  • 순서를 정해주고 싶다.

📌 어떻게 해결했나요

  • @Valid가 아니라 @Validated를 사용해야하고 @GroupSequence를 통해 순서를 정해주면 된다.

    https://dncjf64.tistory.com/302 이 글을 보고 제 상황에 맞게 바꾸어 진행했습니다.


  • 인터페이스를 생성하고 클래스 하나에 모아준다. (따로 만들면 파일이 계속 늘어남)
public class ValidationGroups {
    public interface NotNullGroup {};
    public interface PatternCheckGroup {};
    public interface SizeCheckGroup {};
    public interface EmailCheckGroup {};
}

  • @GroupSequence를 사용하여 원하는 순서대로 정리해준다.
  • 왼쪽부터 유효성 검사를 체크해서 없으면 다음 유효성 검사를 실시하게 된다.
    (❗ 글에서는 Default.class 부터 실시하셧는데 저는 추가하니까 제대로 작동하지 않아서 제외했습니다.)
import com.accountapi.validation.ValidationGroups.NotNullGroup;
import com.accountapi.validation.ValidationGroups.PatternCheckGroup;
import com.accountapi.validation.ValidationGroups.SizeCheckGroup;
import com.accountapi.validation.ValidationGroups.EmailCheckGroup;

import javax.validation.GroupSequence;

@GroupSequence({NotNullGroup.class, SizeCheckGroup.class,
PatternCheckGroup.class, EmailCheckGroup.class})
public interface ValidationSequence {
}

  • dto에 선언되어있는 어노테이션에서 각각 groups = "인터페이스명"을 추가한다.
@Size(min = 4, max = 30, message = "아이디는 4글자에서 30글자 사이로 입력해주세요.", groups = ValidationGroups.SizeCheckGroup.class)
@NotBlank(message = "아이디를 입력해주세요.", groups = ValidationGroups.NotNullGroup.class)
@Pattern(regexp = "^([a-z가-힣0-9]){4,30}$", message = "대문자, 특수문자는 입력할 수 없습니다.", groups = ValidationGroups.PatternCheckGroup.class)
    private String userId;

  • Controller에서 @Valid 사용했던 것을 @Validated로 바꾸어준다.
 @PostMapping
    public ResponseEntity createUser(@Validated(ValidationSequence.class) @RequestBody User signUpInfo) {
        accountManager.createUser(signUpInfo);
        return new ResponseEntity<>(HttpStatus.OK);
    }

📌 마치며 + 아쉬웠던 점

  • 내가 처음에 원했던 것은 각 항목에 대한 개별적인 검사가 필요했는데 모든 항목의 NotNull 검사가 끝날 때까지 다른 검사는 하지않는다.

  • 아이디에 특수문자가 들어있어 에러 메세지를 받을 줄 알았는데 저기 표시된 4개 항목이 채워지기 전까지 Pattern에 대한 검사를 하지 않는다. ㅠㅠ
  • 결론적으로 프론트단과의 적절한 조율을 통하여.. (어차피 내가 만들지만) 그래도 검증은 검증대로 양쪽으로 하면서 편의성도 어느 정도 고려한 결과물이 나온 것 같다.
  • 삽질 얼마나 했는지 모르겠다 ㅋㅋㅋ

📌 reference!

https://dncjf64.tistory.com/302
https://okky.kr/article/381626
https://stackoverflow.com/questions/11804879/error-messages-are-not-in-the-correct-order

profile
공부 기록

0개의 댓글