[Spring,Java] Validator 구현하기

validation

스프링에서 유효성 검사하기 (Spring Validator)

개요

스프링 프레임워크 4.0은 빈 검증기 1.0(JSR-303) 와 1.1(JSR-349)를 지원하며 Spring의 Validator 인터페이스에 적용할 수 있습니다.
어플리케이션은 빈 검증기를 전체에 사용할것인지, 아니면 부분적으로만 사용할것인지 선택할 수 있습니다. 검증 로직의 어노테이션 사용 없이 DataBinder 를 이용하여 Validator 를 추가적으로 등록할 수 있습니다.
DataBinder은 애플리케이션의 도메인모델에 동적으로 바인딩 할 때 유용합니다. 스프링은 데이터바인딩을 하기 위해 DataBinder 을 제공해줍니다. ValidatorDataBinder 는 MVC 프레임워크에서 주로사용되는 유효성 검사 패키지 입니다.
스프링 MVC에서 Validator 인터페이스는 HTML 폼에 있는 모든필드를 검증하기 위해서 사용됩니다. controller 클래스안에 @InitBinder 어노테이션을 이용해서 설정할 수 있습니다.
@InitBinder 어노테이션은 메소드레벨의 어노테이션이며, WebDataBinder 를 초기화하기 위해 사용합니다.
WebDataBinder 클래스는 웹에서 온 request 파라미터들을 model 오브젝트에 바인드를 해줍니다.
자신이 만든 커스텀 Validator 를 컨트롤러에 등록하고 싶다면 WebDataBinder.addValidators() 메소드를 통해 등록이 가능합니다.
인자나, model 오브젝트에 @Validator 어노테이션을 작성하면, 핸들러 메소드가 이를 알고 커스텀 validator를 등록해줍니다.
만약 검증을 위반하는 사항이 발견된다면, 자동적으로 에러가 BindingResult 에게 가게 됩니다.

들어가며

검증기를 사용하는 방법은 두가지가 있습니다.
첫째로 모델 오브젝트에 주석을 사용해서 작성하는 방법과,
두번째로 Validator 인터페이스를 구현하는 방법입니다.

주석을 이용해서 검증하기.

먼저 2개의 필드를 가진 MemberDto 클래스를 만들겠습니다.

MemberDto

id의 길이는 1 부터 30까지 그리고 pw의 길이는 8 부터 30까지 주었고, 오류가 발생시 비밀번호 오류! 라는 메세지를 뿌리도록 작성했습니다.
어노테이션에 대한 설명은 다음과 같습니다.
  • @NotNull - 값이 null인지 체크해줍니다. 그러나 빈배열은 체크를 해주지 못합니다.
  • @Pattern - 값을 주어진 표현식으로만 제한합니다. ex) 값을 영어만 받고싶은 경우@Pattern(regexp=”[^0-9]*”)
  • @Past - 현재보다 과거날짜만 입력가능합니다. ex) 사용자의 생일을 입력할 때
  • @Min - 지정해준 정수값과 같거나 커야합니다.
  • @Max - 지정해준 정수값과 같거나 작아야 합니다.
  • @NotBlank - 문자열이 null인지 체크하고 공백을 제외한 문자열이 0보다 큰지 체크합니다. 이 어노테이션은 JSR 303이 아닙니다.
  • @Email - 유효한 이메일 형식인지 확인합니다. 이 어노테이션 또한 JSR 303이 아닙니다.

MemberController


insert.jsp


비밀번호의 길이가 안맞을 경우

img

아이디를 빈값을 넣을경우에도 메세지 설정을 하지 않아도 default 메세지가 출력된다.

img
어노테이션을 사용하는 방법 깃허브 소스

Validator 인터페이스 구현해서 만들기

스프링 설정 파일

root-context.xml에 다음의 빈을 추가해주세요.
ReloadableResourceBundleMessageSource 빈은 지정된 basename과 스프링의 ApplicationContext 의 리소스 로딩을 이용하여 리소스에 접근이 가능한 MessageSource 의 구현클래스 입니다.
JDK 기반을 둔 ResourceBundleMessageSource 와 반대로, 이 클래스는 스프링의 리소스 핸들러부터 PropertiesPersister 방법을 통해 메세지를 위한 사용자 정의 데이터 Properties 인스턴스를 사용할 수 있습니다.
전형적인 웹 어플리케이션에서 메시지 파일들은 WEB-INF 밑에 두어 사용하는데, 위에와 같이 /WEB-INF/message 로 설정하게 되면 WEB-INF/message.properties WEB-INF/message.xml WEB-INF/message_en.xml 등 모두 인식을 할 수 있습니다.
basename 은 리소스 번들의 위치를 작성해야하며, 반드시 작성해야하는 프로퍼티입니다.

메세지 리소스 파일

이제 유효성 검사에러를 위한 메세지 파일을 하나 만들어 보겠습니다.
/WEB-INF/ 밑에 message.properties 를 생성하겠습니다.

message.properties


MemberDto

아까 변수에 적어줬었던 어노테이션만 제거했습니다.

Validator 인터페이스 구현하기

Validator 인터페이스를 구현하기 위해서 MemberValidator 클래스를 하나 생성해주세요

MemberValidator

Validator를 구현해준 클래스는 빈으로 등록해줘야 하기 때문에 자동으로 빈으로 등록되기 위해서 @Component 어노테이션을 붙여줬습니다.
supports(Class<?> clazz) 에서 구현해줘야 할 것은, 인자로 넘어온 클래스가 이 검증 클래스를 지원하는가? 입니다. 보통 저렇게 쓰거나 , MemberDto.class.isAssignableFrom(clazz); 를 많이 사용합니다.
validate(Object obj, Erros error)에서 구현해줘야 할 것은 어떤걸 검증할 것인가? 를 작성해주면 됩니다. 보통 ValidationUtils 스태틱 클래스를 이용해서 작성합니다.
rejectIfEmpty 는 오버로딩 메소드라서 원하는 메소드를 골라서 사용하면 됩니다.
예제에서 사용했던 메소드는 인자가 4개짜리인데요, 첫번째 인자에는 그냥 error를 담아주고, 2번째 인자에는 필드이름을 적어줍니다. 3번째 인자에는 message.properties에 적었던 이름을 적어주면 됩니다. 4번째 인자에는 만약 3번째 인자의 값을 못찾을 경우 디폴트로 나타내줄 메세지를 적어주시면 됩니다.
또한 넘어온 도메인의 값을 검증하고 싶다면 Pattern 클래스를 이용해서 해당 값을 검증을 할 수 있습니다.
ValidationUtils
Pattern

MemberController

컨트롤러에서 앞에서 구현해준 memberValidatorDI 해주고, @initBinder 어노테이션을 이용해서 validator를 추가해주면 정상적으로 동작을 합니다.
index.jsp는 수정 없이 그대로 사용해도 됩니다.

정상적으로 동작하는 모습

img
Validator 깃허브 소스

마치며

자바스크립트에서 유효성 검사를 하지만 자바스크립트의 유효성 검사만으로는 안됩니다.
자바스크립트의 유효성 검사는 서버에 전송되는 횟수를 막아주는 것 일뿐,
서버에서도 유효성 검사를 반드시 해주어야 합니다.

댓글

이 블로그의 인기 게시물

Filter url 제외시키기

[Spring] Mock framework에 대하여