백엔드/스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

검증2 - Validation

넌 감동란이었어 2023. 3. 15. 16:05

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