지난 포스팅에서 Bean Validation을 다루었다.
Bean Validation은 어노테이션 기반으로 유효성 검사를 진행하는 검증 방식이다. 검증 과정에서 발견한 에러는 BindingResult에 담긴다. BindingResult에 담긴 에러는 에러코드 형태로 담긴다. 그럼 화면에서 에러를 일으켜 보자.
Item 클래스
@Data
public class Item {
private Long id;
@NotBlank
private String itemName;
@NotNull
@Range(min=1000,max=1000000)
private Integer price;
@NotNull
@Max(9999)
private Integer quantity;
}
상품명에는 @NotBlank 에러를, 가격란에는 @Range 에러를, 수량에는 @NotNull 에러를 일으켰다. 그럼 BindingResult에는 어떤 에러코드가 담길까?
Controller 메소드
@PostMapping("/add")
public String addItem(@Validated @ModelAttribute Item item, BindingResult bindingResult) {
if(bindingResult.hasErrors()){
log.info("errors={}",bindingResult);
return "validation/addForm";
}
}
Controller에서 BindingResult에 담긴 에러를 로그로 찍고 에러코드만 추출해보았다.
- 'itemName': [NotBlank.item.itemName,NotBlank.itemName,NotBlank.java.lang.String,NotBlank]
- 'price': [Range.item.price,Range.price,Range.java.lang.Integer,Range]
- 'quantity' : [NotNull.item.quantity,NotNull.quantity,NotNull.java.lang.Integer,NotNull]
한 가지 에러에 매핑되는 에러코드는 4가지이다. 가장 왼쪽부터 우선순위가 높다.
item 필드의 @NotBlank 에러
- NotBlank.item.itemName
- NotBlank.itemName
- NotBlank.java.lang.String
- NotBlank
price 필드의 @Range 에러
- Range.item.price
- Range.price
- Range.java.lang.Integer
- Range
quantity 필드의 @NotNull 에러
- NotNull.item.quantity
- NotNull.quantity
- NotNull.java.lang.Integer
- NotNull
에러메시지는 에러코드와 매핑되어 출력된다. 그러므로 에러메시지 파일을 에러코드를 기준으로 정리해야 한다.
application.properties
spring.messages.basename=errors
Spring에게 메시지 파일 위치를 알려주기 위해 application.properties에 위 설정을 추가한다.
errors.properties
#== 우선순위 0순위 ==
NotBlank.item.itemName=[ 우선순위 0순위 ] 상품 이름은 필수입니다.
Range.item.price=[ 우선순위 0순위 ] 가격은 {2} ~ {1} 까지 허용합니다.
NotNull.item.quantity = [ 우선순위 0순위 ] 수량을 입력해주세요
#== 우선순위 1순위 ==
NotBlank.itemName=[ 우선순위 1순위 ] 상품 이름을 비어있습니다.
Range.price=[ 우선순위 1순위 ]가격이 범위 밖에 있습니다.
NotNull.quantity=[ 우선순위 1순위 ]수량을 입력해주세요
#== 우선순위 2순위 ==
NotBlank.java.lang.String=[ 우선순위 2순위 ] 필수 문자 입니다.
Range.java.lang.Integer= [ 우선순위 2순위 ] 범위 밖의 수를 입력했습니다.
NotNull.java.lang.Integer= [ 우선순위 2순위 ]정수를 입력해주십시오
#== 우선순위 3순위 ==
Range=[ 우선순위 3순위 ] 범위 밖에 습니다.
NotBlank=[ 우선순위 3순위 ] 빈값은 허용되지 않습니다.
NotNull=[ 우선순위 3순위 ] null값은 허용하지 않습니다.
errors.properties에는 에러 코드와 매핑되는 에러 메시지를 설정한다. Spring은 우선순위대로 에러코드를 읽어 에러메시지를 출력한다. 0순위가 없으면 1순위, 1순위가 없으면 2순위, 2순위가 없으면 3순위, 3순위가 없으면 디폴트 메시지를 출력한다.
화면을 실행하면 위와 같이 에러 메시지가 변경된 것을 확인할 수 있다. 그럼 0순위 오류메시지를 설정에서 지우고 다시 실행해보겠다.
0순위가 없으니 1순위가 출력되었다.
Bean Validation은 어노테이션마다 지정된 에러코드가 존재하고 이를 우선순위별로 제공한다. 에러코드를 이용하면 Bean Validation 과정에서 발생하는 에러에 에러메시지를 설정할 수 있다.
typeMismatch
typeMismatch는 Bean Validation과 관련없지만 에러코드를 다루는 김에 같이 다루어 보겠다.
Bean Validation은 유효성 검사에서 사용하는 검증이다. Bean Validation이 동작하기 이전에 @ModelAttribute로 선언된 객체에 요청 데이터를 바인딩 하는 과정에서 에러가 발생할 수 있다.
가격란에 int형 데이터가 아닌 문자열이 입력되었다. 그랬더니 위 사진과 같은 에러 메시지가 출력되었다. 이는 Spring이 바인딩 에러를 BindingResult에 담을 때 설정한 디폴트 메시지이다. Spring은 바인딩 과정에서 발생한 에러 관련 에러코드를 제공한다.
바인딩 에러 코드
- typeMismatch.item.price
- typeMismatch.price
- typeMismatch.java.lang.Integer
- typeMismatch
위부터 우선순위가 높다. 그러므로 에러코드를 에러메시지 파일에 설정하면 원하는 에러메시지를 출력할 수 있다.
##== 우선순위 0순위 ==
NotBlank.item.itemName=[ 우선순위 0순위 ] 상품 이름은 필수입니다.
Range.item.price=[ 우선순위 0순위 ] 가격은 {2} ~ {1} 까지 허용합니다.
NotNull.item.quantity = [ 우선순위 0순위 ] 수량을 입력해주세요
#== 우선순위 1순위 ==
NotBlank.itemName=[ 우선순위 1순위 ] 상품 이름을 비어있습니다.
Range.price=[ 우선순위 1순위 ]가격이 범위 밖에 있습니다.
NotNull.quantity=[ 우선순위 1순위 ]수량을 입력해주세요
#== 우선순위 2순위 ==
NotBlank.java.lang.String=[ 우선순위 2순위 ] 필수 문자 입니다.
Range.java.lang.Integer= [ 우선순위 2순위 ] 범위 밖의 수를 입력했습니다.
NotNull.java.lang.Integer= [ 우선순위 2순위 ]정수를 입력해주십시오
#== 우선순위 3순위 ==
Range=[ 우선순위 3순위 ] 범위 밖에 습니다.
NotBlank=[ 우선순위 3순위 ] 빈값은 허용되지 않습니다.
NotNull=[ 우선순위 3순위 ] null값은 허용하지 않습니다.
#== 추가 ==
typeMismatch.java.lang.Integer=숫자를 입력해주세요.
typeMismatch=타입 오류입니다.
errors.properties에 설정을 추가하였더니 디폴트 메시지가 아닌 설정된 메시지가 출력되었다. 이처럼 Spring은 에러코드를 제공하고 개발자는 에러코드를 key값으로 하여 에러메시지를 설정할 수 있다.
참고자료
'SPRING > Spring MVC' 카테고리의 다른 글
[SpringMVC] 검증(Validation)(8) - Bean Validation ( 폼객체 ) (0) | 2023.08.30 |
---|---|
[SpringMVC] 검증(Validation)(7) - Bean Validation ( groups ) (0) | 2023.08.30 |
[SpringMVC] 검증(Validation)(5) - Bean Validation (0) | 2023.08.29 |
[SpringMVC] 검증(Validation)(4) - BindingResult ( @Validated ) (0) | 2023.08.28 |
[SpringMVC] 검증(Validation)(3) - BindingResult ( rejectValue 메소드 ) (0) | 2023.08.28 |