지난 포스팅에서 Bean Validation에 대해서 다루어보았다.
Bean Validation은 객체에 주입된 데이터를 검증하는 어노테이션 기반 검증 방식이다. 그런데 여기에는 한 가지 문제가 있다.
Item 클래스
@Data
public class Item {
private Long id;
@NotBlank
private String itemName;
@NotNull
@Range(min=1000,max=1000000)
private Integer price;
@Max(9999)
private Integer quantity;
}
Controller
// 저장 메소드
@PostMapping("/add")
public String addItem(@Validated @ModelAttribute Item item, BindingResult bindingResult) {
// 중략 ...
}
// 수정 메소드
@PostMapping("/edit")
public String edit(@PathVariable Long itemId, @Validated @ModelAttribute Item item, BindingResult bindingResult) {
// 중략 ...
}
저장 메소드와 수정 메소드가 모두 Item 클래스를 파라미터로 갖는다. 그리고 @Validated를 선언하여 유효성 검사를 한다. 문제는 저장 할 때와 수정 할 때 데이터에 대한 유효성 기준이 달라진다는 점이다.
예를 들어,
저장 메소드가 호출되면 Item 객체의 id는 null이어도 상관없다. 어차피 신규 id가 내부로직에서 생성되기 때문이다. 그러나 수정 메소드가 호출되면 반드시 id가 있어야 한다. 저장 시에는 @NotNull 유효성 검사를 안해도 되지만 수정 시에는 @NotNull 검사를 해야한다. 이렇듯 Item 클래스를 두고 서로 다른 유효성 기준을 가지고 있는 것이다.
이를 어떻게 해결해야 할까?
groups
Bean Validation은 groups라는 설정을 제공한다.
SaveCheck 클래스
public interface SaveCheck {
}
UpdateCheck 클래스
public interface UpdateCheck {
}
Item 클래스
@Data
public class Item {
@NotNull(groups = UpdateCheck.class)
private Long id;
@NotBlank(groups = {SaveCheck.class,UpdateCheck.class})
private String itemName;
@NotNull(groups = {SaveCheck.class,UpdateCheck.class})
@Range(min=1000,max=1000000,groups = {SaveCheck.class,UpdateCheck.class})
private Integer price;
@NotNull(groups = {SaveCheck.class,UpdateCheck.class})
@Max(value=9999,groups = SaveCheck.class)
private Integer quantity;
}
어노테이션의 groups 설정에 유효성 검사를 적용할 인터페이스 클래스명을 설정하는 것이다. 그럼 Controller를 보자.
Controller
// 저장 메소드
@PostMapping("/add")
public String addItem(@Validated(SaveCheck.class) @ModelAttribute Item item, BindingResult bindingResult) {
// 중략 ...
}
// 수정 메소드
@PostMapping("/edit")
public String edit(@PathVariable Long itemId, @Validated(UdateCheck.class) @ModelAttribute Item item, BindingResult bindingResult) {
// 중략 ...
}
저장메소드는 @Validated(SaveCheck.class)가 선언되어 있다. 이는 SaveCheck.class 그룹으로 유효성 검사를 실시하겠다는 의미이다. 그럼 Item 클래스의 groups에 SaveCheck.class가 설정되어 있는 어노테이션만 유효성 검사를 실시한다.
예를 들어, @NotNull(groups = UpdateCheck.class)의 의미는 UpdateCheck.class를 그룹으로 하는 검증만 유효성 검사를 하겠다는 의미이다. 수정메서드가 UpdateCheck.class로 유효성 검사를 요청하니, id 필드의 NotNull 검사는 수정메서드에서만 이루어 진다.
이처럼 groups 설정을 이용하면 Item 클래스 하나로도 각기 다른 유효성 검사를 적용할 수 있다. 그러나 코드를 보면 알 수 있듯이, Item 클래스가 지저분해지고 그룹을 나누기 위한 의미없는 인터페이스도 계속 만들어야 한다. 그래서 groups 설정은 실무에서는 잘 사용하지 않는 방식이다. 실무에서는 form 객체를 생성하여 문제를 해결한다. 이는 다음 포스팅에서 다루어 보겠다.
참고자료
'SPRING > Spring MVC' 카테고리의 다른 글
[SpringMVC] Cookie ( 쿠키 ) (0) | 2023.08.30 |
---|---|
[SpringMVC] 검증(Validation)(8) - Bean Validation ( 폼객체 ) (0) | 2023.08.30 |
[SpringMVC] 검증(Validation)(6) - Bean Validation ( 에러 코드 ) (0) | 2023.08.29 |
[SpringMVC] 검증(Validation)(5) - Bean Validation (0) | 2023.08.29 |
[SpringMVC] 검증(Validation)(4) - BindingResult ( @Validated ) (0) | 2023.08.28 |