Dev/Spring

[Spring] @Valid, @Validated 활용

창문닦이 2020. 7. 15. 01:28

@Valid 어노테이션을 활용한 유효성 검사 로직을 리팩토링 하면서 공부해보았다. 기존 소스도 파라미터 체크 로직을 이걸로 수정해서 반영해놓았다. 뿌듯하다 ㅎㅎ. 파볼수록 흥미로운 게 많아 정리한다. documents 읽기를 생활화하자!

 

1. Validator란?

스프링에서 도메인 객체를 검증할 수 있도록 제공하는 인터페이스. 

- Controller로 HTTP 요청을 @ModelAttribute 모델에 바인딩할 때 주로 사용된다.

- Validator 인터페이스는 supports()와 validate() 메서드로 구성되어 있다.

supports()는 이 검증기가 검증할 수 있는 오브젝트 타입인지 확인해주는 메서드, 이 메서드를 통과한 경우에만 validate()가 호출된다.

validate()는 매개변수로 전달된 객체를 검증하고 실패하면 Errors 객체에 에러를 등록한다.

## Errors인터페이스와 BindingResult인터페이스

org.sprigFramework.validation.Errors : 유효성 검증 결과를 저장할 떄 사용

org.springFramework.validation.BindingResult : Errors의 하위 인터페이스로서 폼 값을 커맨드 객체에 바인딩한 결과를 저장하고 에러코드로 메시지를 가져온다.

 

2. Maven Dependencies

SpringBoot-web 모듈을 선택했다면 자동으로 들어가있지만 Spring이라면 pom.xml에 추가해줘야 한다.

<!-- Validation -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

 

3.  @Valid 어노테이션 및 유효성 검사 어노테이션 : 검증할 VO 객체나 파라미터에 사용한다.

  • @AssertFalse : false 값만 통과 가능
  • @AssertTrue : true 값만 통과 가능
  • @DecimalMax(value=) : 지정된 값 이하의 실수만 통과 가능
  • @DecimalMin(value=) : 지정된 값 이상의 실수만 통과 가능
  • @Digits(integer=,fraction=) : 대상 수가 지정된 정수와 소수 자리수보다 적을 경우 통과 가능
  • @Future : 대상 날짜가 현재보다 미래일 경우만 통과 가능
  • @Past : 대상 날짜가 현재보다 과거일 경우만 통과 가능
  • @Max(value) : 지정된 값보다 아래일 경우만 통과 가능
  • @Min(value) : 지정된 값보다 이상일 경우만 통과 가능
  • @NotNull : null 값이 아닐 경우만 통과 가능
  • @NotEmpty :
  • @Null : null일 겨우만 통과 가능
  • @Pattern(regex=, flag=) : 해당 정규식을 만족할 경우만 통과 가능
  • @Size(min=, max=) : 문자열 또는 배열이 지정된 값 사이일 경우 통과 가능
  • @Valid : 대상 객체의 확인 조건을 만족할 경우 통과 가능. Spring3부터 Spring MVC에서는 컨트롤러 메서드의 파라미터를 자동으로 검증하는 이 자동 검증 어노테이션을 제공. 

4. 오류 발생 시 메세지를 바로 설정하거나 하나의 파일로 관리 가능

 

> 메세지 소스 관련 빈 설정 (빈 이름 설정을 잘못할 경우 계속 프로퍼티 파일에 설정한 메세지값을 제대로 못읽어온다. 주의하자 ㅠㅠ)

@Configuration
public class WebConfiguration implements WebMvcConfigurer {
	@Bean
	public MessageSource messageSource() {
		ReloadableResourceBundleMessageSource messageSource =
				new ReloadableResourceBundleMessageSource();
		messageSource.addBasenames("classpath:messages"); 	//resources 경로와 일치시킬 것!
		messageSource.setDefaultEncoding("UTF-8");
		return messageSource;
	}
	
	@Bean
	public LocalValidatorFactoryBean getValidator(MessageSource messageSource) {
		LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
		bean.setValidationMessageSource(messageSource);
		return bean;
	}
    // 이 외 생략
}

> VO 객체에 설정된 유효성 검사

@NotEmpty(message = "{seq.NotEmpty}") //원하는 메세지를 바로 설정하거나 name으로 처리 가능
private int seq;

> message.properties 프로퍼티 파일에 설정된 메시지 텍스트 내용

seq.NotEmpty=일련번호는 빈 값을 허용하지 않습니다.

> 컨트롤러

@RestController
public class TestController {

	@PostMapping(value = "/test")
	public ResponseEntity<Void> testValid(@Valid @ModelAttribute TestVO test, BindingResult result) {
		log.info("TestVO: {}", test);
		return ResponseEntity.noContent().build();
	}
}

 

5. 제약 조건중 일부만 적용하고 싶다면 인터페이스를 활용한 제약조건 Group 사용(단, @Validated 어노테이션 사용해야 함. @Valid는 지원하지 않는다.)

public interface Default;	

@NotEmpty(message = "{seq.NotEmpty}", groups={Default.class})
private int seq;

 

 


Reference 

https://medium.com/@gaemi/java-%EC%99%80-spring-%EC%9D%98-validation-b5191a113f5c

https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/validation.html#validation-beanvalidation

https://smiler.tistory.com/entry/Validator

https://lazymankook.tistory.com/86

 

'Dev > Spring' 카테고리의 다른 글

[Spring] EHCache  (0) 2020.05.06
[Spring] Annotation 간략 정리  (0) 2019.12.11
Spring3.0 - Spring WEB MVC  (0) 2019.04.19
Spring3.0 - MVC web & MyBatis  (0) 2019.04.18
Spring3.0 - MVC web & JDBC 게시판만들기  (0) 2019.04.18