1. Bean Validaion - 소개
Bean Validation 이란 검증 애노테이션과 여러 인터페이스의 모음이다.
2. Bean Validation - 시작
implementation 'org.springframework.boot:spring-boot-starter-validation' 를 build.gradle에 추가해야한다.
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class Item {
private Long id;
@NotBlank
private String itemName;
@NotNull
@Range(min = 100, max = 1000000)
private Integer price;
@NotNull
@Max(9999)
private Integer quantity;
public Item() {
}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
@NotBlank : 빈값 + 공백만 있는 경우를허용하지않는다.
@NotNull : null 을허용하지않는다.
@Range(min = 1000, max = 1000000) : 범위 안의값이어야한다.
@Max(9999) : 최대 9999까지만허용한다.
3. Bean Validation - 스프링 적용
@Validated를 사용하면 된다.
4. Bean Validation - 에러 코드
에러 코드를 수정할 수 있다.
#Bean Validation 추가
NotBlank={0} 공백X
Range={0}, {2} ~ {1} 허용
Max={0}, 최대 {1}
이렇게 수정할 수 있다.
5. Bean Validation - 오브젝트 오류
@ScriptAssert()를 사용하여 오브젝트 오류를 해결 할 수 있다.
@Data
@ScriptAssert(lang = "javascript", script = "_this.price * _this.quantity >= 10000", message = "10000원 넘게 입력해주세요.")
public class Item {
실무에서는 검증 기능이 해당 객체의 범위를 넘어서는 경우가 종종 있기 때문에 잘 사용되지 않고
직접 자바 코드로 작성하는 것을 권장한다.
5. Bean Validation - 수정에 적용
수정코드만 따로 수정해주면 된다.
6. Bean Validation - 한계
등록을 할 때는 검증이 잘 이루어지지만 수정시에는 검증이 이루어지지 않는다.
ex) 1. quantity는 수량을 최대 9999까지 등록할 수 있지만 수정시에는 수량을 무제한으로 변경할 수 있다.
2. 등록시에는 id에 값이 없어도 되지만, 수정시에는 id값이 필수이다.
7. Bean Validation - groups
동일한 모델 객체를 등록할 때와 수정할 때의 각각 다르게 검증하는 방법이 있다.
groups는 검증할 기능과 수정시에 검증할 기능을 각각 나누어 적용할 수 있다.
수정용 groups
public interface UpdateCheck {
}
저장용 groups
public interface SaveCheck {
}
이렇게 groups로 나눌 수 있다.



하지만 groups에 문제점이 있다.
groups의 기능을 사용하면 Item 객체 등의 복잡도가 올라간다.
8. Form 전송객체 분리 - 개발
위에 문제를 해결하기 위해 각각 Item 저장용 폼, 수정용 폼을 만든다.


9. Bean Validation - HTTP 메시지 컨버터
@Validated는 httpMessageConverter에도 적용할 수 있다.
참고
> @ModelAttribute 는 HTTP 요청파라미터(URL 쿼리 스트링, POST Form)를 다룰때 사용한다.
> @RequestBody 는 HTTP Body의 데이터를객체로변환할 때사용한다. 주로 API JSON 요청을 다룰때
사용한다.
API의경우 3가지경우를 나누어생각해야한다.
성공요청: 성공
실패요청: JSON을 객체로생성하는것 자체가실패함
검증오류요청: JSON을객체로생성하는것은성공했고, 검증에서 실패함
API의경우 3가지경우를 나누어생각해야한다.
성공요청: 성공
실패요청: JSON을 객체로생성하는것 자체가실패함
검증오류요청: JSON을객체로생성하는것은성공했고, 검증에서 실패함
@ModelAttribute vs @RequestBody
HTTP 요청 파리미터를 처리하는 @ModelAttribute 는 각각의필드 단위로 세밀하게적용된다. 그래서
특정필드에타입이 맞지않는오류가 발생해도나머지필드는 정상처리할 수있었다.
HttpMessageConverter 는 @ModelAttribute 와다르게 각각의필드 단위로적용되는것이아니라,
전체객체단위로 적용된다.
따라서메시지 컨버터의작동이 성공해서 ItemSaveForm 객체를 만들어야 @Valid , @Validated 가
적용된다.
@ModelAttribute 는 필드단위로정교하게바인딩이적용된다. 특정필드가 바인딩되지않아도 나머지
필드는정상 바인딩 되고, Validator를 사용한검증도적용할수 있다.
@RequestBody 는 HttpMessageConverter 단계에서 JSON 데이터를객체로변경하지 못하면이후
단계자체가진행되지 않고예외가발생한다. 컨트롤러도 호출되지않고, Validator도적용할수 없다.
이게 사실 무슨말인지 모르겠다.. 추후 프로젝트를 직접 경험해보고 나서 다시 읽어보면 도움이 될 것 같아 작성해놨다
'백엔드 > 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술' 카테고리의 다른 글
검증1 - Validation (0) | 2023.03.07 |
---|---|
메시지, 국제화 (0) | 2023.01.28 |
타임리프 - 기본 기능 (0) | 2023.01.23 |