FireDrago
[Spring] 검증처리 본문

스프링은 클라이언트가 잘못된 입력값을 입력했을때 유효성을 검사하고, 발생한 에러를 처리하는 편리한 기능을 제공한다
이러한 검사는 클라이언트 단계에서 할 수도 있지만, 조작과 보안 위험이 있으므로 서버단에서도 반드시 검사해야한다
< BindingResult >
스프링은 BindingResult 인터페이스를 통하여 여러 에러상황을 저장하고 오류메시지를 전달하는 기능을 한다.
반드시 @ModelAttribute 객체의 바로뒤에서 호출해야한다.
addError( ) 를 사용하면, 사용자의 잘못입력한 값을 그대로 전달 할 수 있다.
필드값의 에러인 경우 FieldError , 그외 에러인 경우 ObjectError 객체를 생성하여 파라미터로 전달한다.
코드를 살펴보자

FieldError 객체의 생성자는 사용자의 잘못된 입력값을 저장하고, 오류메시지를 만드는데 필요한 값을 받는다.
objectName : 오류가 발생한 객체 이름
field : 오류 필드
rejectedValue : 사용자가 입력한 값(거절된 값)
bindingFailure : 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값
codes : 메시지 코드
arguments : 메시지에서 사용하는 인자
defaultMessage : 기본 오류 메시지
파라미터의 타입오류 등 바인딩에서 발생한 오류처리에 쓰이는
ObjectError 역시 오류필드 값을 받지않는다는 점 빼고 FieldError와 같다
<Thymeleaf>

여기서 스프링과 연계된 타임리프의 편리함을 알 수 있다. 코드로 살펴보자


BindingResult에 ObjectError 가 있으면 태그를 표시하기 위해 #fields.hasGlobalErrors()를 사용했다.
#fields.hasErrors('필드명') 을 사용하면 특정 필드의 에러도 확인 할 수 있다.
두번째 이미지에서 th:errorclass="field-error" 를 통해 에러가 있는경우 class 속성을 추가할수 있도록 했다.
th:errors="*{price}" 는 앞의 코드에서 th:object="객체" 로 정의된 객체의 price필드에 에러가 있을경우 태그를 표시한다
th:field는 엄청 똑똑하게 작동하는데, 오류가 있으면, 필드의 오류값을, 오류가 없으면 정상적인 값을 value로 출력한다
< rejectValue( ) , reject( ) >
addErrors( ) 메서드는 여러기능을 지원하지만 파라미터가 많아, 코드가 복잡해진다.
그래서 BindingResult 인터페이스는 reject (객체), rejectValue(필드) 메서드를 통해 편리한 오류처리를 지원한다.
어차피 BindingResult 는 @ModelAttribute 바로뒤에 호출되므로, 객체이름은 이미 알 수 있다.
파라미터로 전달 할 필요가 없는 것이다. 코드로 살펴보자

addError( ) 보다 훨씬 더 간결한 코드로 에러는 처리 할 수 있다.
그런데 에러코드를 addError( ) 보다 훨씬 단순하게 처리한 것이 보인다.
MessageCodeResolver 가 내부에서 에러코드를 생성해주기 때문이다. 에러코드에 대하여 알아보자
< 에러코드 >
MessageCodeResolver는 객체오류, 필드오류에 따라 오류코드를 다른 순서로 생성한다.
객체 오류의 경우 다음 순서로 2가지 생성
1.: code + "." + object name
2.: code
예) 오류 코드: required, object name: item
1.: required.item
2.: required
필드 오류의 경우 다음 순서로 4가지 메시지 코드 생성
1.: code + "." + object name + "." + field
2.: code + "." + field
3.: code + "." + field type
4.: code
예) 오류 코드: typeMismatch, object name "user", field "age", field type: int
1. "typeMismatch.user.age"
2. "typeMismatch.age"
3. "typeMismatch.int"
순서대로 생성된 에러코드에 맞는 에러메시지를 properties 파일에서 찾고, 해당되는 에러메시지가 있는경우 출력한다.
#==ObjectError==
#Level1
totalPriceMin.item=상품의 가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
#Level2 - 생략
totalPriceMin=전체 가격은 {0}원 이상이어야 합니다. 현재 값 = {1}
#==FieldError==
#Level1
required.item.itemName=상품 이름은 필수입니다.
range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
max.item.quantity=수량은 최대 {0} 까지 허용합니다.
#Level2 - 생략
#Level3
required.java.lang.String = 필수 문자입니다.
required.java.lang.Integer = 필수 숫자입니다.
min.java.lang.String = {0} 이상의 문자를 입력해주세요.
min.java.lang.Integer = {0} 이상의 숫자를 입력해주세요.
range.java.lang.String = {0} ~ {1} 까지의 문자를 입력해주세요.
range.java.lang.Integer = {0} ~ {1} 까지의 숫자를 입력해주세요.
max.java.lang.String = {0} 까지의 문자를 허용합니다.max.java.lang.Integer = {0} 까지의 숫자를 허용합니다.
#Level4
required = 필수 값 입니다.
min= {0} 이상이어야 합니다.
range= {0} ~ {1} 범위를 허용합니다.
max= {0} 까지 허용합니다.
#추가
typeMismatch.java.lang.Integer=숫자를 입력해주세요.
typeMismatch=타입 오류입니다.
스프링은 타입 오류가 발생하면 typeMismatch 라는 오류 코드를 사용한다.
생성된 오류 코드를 순서대로 조회한뒤, 해당 오류코드의 메시지를 출력하는 방식이다.
즉 개발자는 구체적인 오류메시지 부터, 범용적인 메시지 순으로 작성하면, 뷰의 코드 변경없이
오류메시지를 상황에 맞게 출력 할 수 있게된다.
< Validator 추출>

스프링은 간단한 방법으로 에러처리하는 방법을 제공한다.


컨트롤러에 @InitBInder 와 함께 WebDataBinder 를 사용하여 사용자 지정 검증 클래스를 지정한다.
이렇게 되면 @validated 붙은 메서드는 실행시 검증 클래스가 자동으로 실행된다.

사용자 지정 클래스는 스프링이 제공하는 Validator 인터페이스를 구현한다.
support 메서드는 해당 isAssignableFrom 을 통해 Item 클래스의 인스턴스거나 자손 인스턴스 인지 확인한다.
validate 메서드에 원하는 검증로직을 수행하도록 하면 된다. 이때 인자로 Errors (BindingResult 조상) 타입을 받는다.
'프로그래밍 > Spring' 카테고리의 다른 글
| [Spring] 로그인 쿠키와 세션 (0) | 2024.02.14 |
|---|---|
| [Spring] Bean Validation (0) | 2024.02.12 |
| [Spring] HttpMessageConverter (0) | 2024.02.01 |
| [Spring] Spring 기본기능 (0) | 2024.01.30 |
| [Spring] Spring MVC 기본구조 (0) | 2024.01.26 |
