Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Bean Validation - HTTP 메시지 컨버터 본문

인프런/[인프런] 스프링 MVC 2

Bean Validation - HTTP 메시지 컨버터

Seung__ 2021. 9. 25. 21:05

@Valid , @Validated 는 HttpMessageConverter ( @RequestBody )에도 적용할 수 있음.

 

1. @ModelAttribute, @RequestBody


  • @ModelAttribute :  HTTP 요청 파라미터(URL 쿼리 스트링, POST Form)를 다룰 때 사용
  • @RequestBody : HTTP Body의 데이터를 객체로 변환할 때 사용한다.
    주로 API JSON 요청을 다룰 때 사용

 

 

2. Controller


  •  @RestController = @Controller  + @ReponseBody
  •  @RequestBody : JSON 데이터를 객체로 바꿔줌.
@Slf4j
@RestController
@RequestMapping("/validation/api/items")
public class ValidationItemApiController {

    //@ResponseBody
    @PostMapping("/add")
    public Object addItem(@RequestBody @Validated ItemSaveForm form, BindingResult bindingResult){

        log.info("API Controller 호출");

        if(bindingResult.hasErrors()){
            log.info("검증 오류 발생, errors = {}", bindingResult);
            return bindingResult.getAllErrors();

        }

        log.info("성공 로직 실행");

        return form;
    }
}

 

 

 

3. API경우 3가지 경우로 나누어서 생각


  • 성공 요청: 성공
{
    "itemName": "hello",
    "price": 1000,
    "quantity": 10
}
  • 실패 요청: JSON을 객체로 생성하는 것 자체가 실패함
    • 따라서 controller가 호출되지 않음.
{
    "itemName": "hello",
    "price": "a",
    "quantity": 10
}
{
    "timestamp": "2021-09-25T11:40:50.108+00:00",
    "status": 400,
    "error": "Bad Request",
    "path": "/validation/api/items/add"
}
  • 검증 오류 요청: JSON을 객체로 생성하는 것은 성공했고, 검증에서 실패함
{
    "itemName": "hello",
    "price": 1,
    "quantity": 10
}
[
    {
        "codes": [
            "Range.itemSaveForm.price",
            "Range.price",
            "Range.java.lang.Integer",
            "Range"
        ],
        "arguments": [
            {
                "codes": [
                    "itemSaveForm.price",
                    "price"
                ],
                "arguments": null,
                "defaultMessage": "price",
                "code": "price"
            },
            1000000,
            1000
        ],
        "defaultMessage": "1000에서 1000000 사이여야 합니다",
        "objectName": "itemSaveForm",
        "field": "price",
        "rejectedValue": 1,
        "bindingFailure": false,
        "code": "Range"
    }
]
2021-09-25 20:53:41.643  INFO 29488 --- [nio-8080-exec-3] h.i.w.v.ValidationItemApiController
: API Controller 호출

2021-09-25 20:53:41.643  INFO 29488 --- [nio-8080-exec-3] h.i.w.v.ValidationItemApiController
: 검증 오류 발생, errors = org.springframework.validation

 

 

 

4. bindingResult.getAllErrors()


  • ObjectError 와 FieldError 를 반환한다. 
  • 스프링이 이 객체를 JSON으로 변환해서 클라이언트에 전달했다. .
  • 실제로는 필요한 데이터만 뽑아서 별도의 API 스펙을 정의함. 이에 맞는 객체를 만들어서 반환

 

5. @ModelAttribute vs @RequestBody


  • HTTP 요청 파리미터를 처리하는 @ModelAttribute 는 필드 단위로 적용됨.
  • 그래서 특정 필드에 타입이 맞지 않는 오류가 발생해도 나머지 필드는 정상적으로 처리 가능.
  • Validator를 사용한 검증도 적용할 수 있다.

  • @RequestBody를 사용하면 HttpMessageConverter를 사용하는데,
  • HttpMessageConverter는 @ModelAttribute 와 다르게 각각의 필드 단위로 적용되는 것이 아니라,
  • 객체 단위로 적용된다.
  • 따라서 HttpMesageConverter의 작동이 성공해서 JSON -> 객체 변환이 성공해야
  • @Valid , @Validated 가 적용된다.
  • 만약 HttpMessageConverter에서 JSON -> 객체 변환에 실패하면 예외가 발생하고.
  • Controller 호출이 안되고, Validator도 동작하지 않음

  • @ModelAttribute 는 필드 단위로 정교하게 바인딩이 적용된다. 
  • 특정 필드가 바인딩 되지 않아도 나머지 필드는 정상 바인딩 되고, Validator를 사용한 검증도 적용할 수 있다.
  • @RequestBody 는 HttpMessageConverter 단계에서 JSON 데이터를 객체로 변경하지 못하면 이후
  • 단계 자체가 진행되지 않고 예외가 발생한다.
  •  컨트롤러도 호출되지 않고, Validator도 적용할 수 없다.

 

6. GitHub : 210925 Bean Validation, API


 

GitHub - bsh6463/Validation-V1

Contribute to bsh6463/Validation-V1 development by creating an account on GitHub.

github.com

 

Comments