ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring MVC - HTTP API 메시지(JSON)의 Bean Validation
    Spring/Spring MVC 2022. 2. 7. 16:58
    반응형

     

     

     

    HTTP API 메시지(JSON)의 Bean Validation

    • @ModelAttribute : HTTP 요청 파라미터(URL 쿼리 파라미터, POST Form)를 타룰 때 사용
    • @RequestBody : HTTP Body의 데이터를 객체로 변환할 때 사용(JSON)

     

     Bean Validation는 HttpMessageConverter를 사용하는 @RequestBody에도 적용할 수 있다.

     

     API Bean Validation

     

    • 데이터 바인딩 시 타입 검증 오류가 발생하면 JSON을 객체로 생성하는 것 자체를 실패한다.
      (객체 생성에 실패하면 컨트롤러 자체가 호출되지 않고 예외가 발생)
    • 타입 검증을 통과하면 JSON을 객체로 생성하여 Bean Validation을 수행한다.

     

    @Slf4j
    @RestController
    @RequestMapping("/validation/api/items")
    public class ValidationItemApiController {
    
        @PostMapping("/add")
        public Object addItem(@Validated @RequestBody ItemSaveForm form, BindingResult bindingResult) {
    
            log.info("API 컨트롤러 호출");
    
            if (bindingResult.hasErrors()) {
                log.info("검증 오류 발생 errors={}", bindingResult);
                return bindingResult.getAllErrors();
            }
    
            log.info("성공 로직 실행");
            return form;
        }
    }

     

     

    Postman으로 JSON 형식으로 상황에 따른 요청 메시지를 보내보자.

     

    1. 타입 검증 오류가 발생하여 컨트롤러를 호출하지 못하고 예외가 발생
      {"itemName":"hello", "price":B, "quantity": 100}​
      응답 메시지 바디
      {
          "timestamp""2022-02-07T07:37:53.706+00:00",
          "status"400,
          "error""Bad Request",
          "message""",
          "path""/validation/api/items/add"
      }


    2. 타입 검증을 통과했지만 필드 바인딩 과정에서 검증 오류 발생
      {"itemName":"hello", "price":1000, "quantity": 10000}
      응답 메시지 바디
      [
          {
              "codes": [
                  "Max.itemSaveForm.quantity",
                  "Max.quantity",
                  "Max.java.lang.Integer",
                  "Max"
              ],
              "arguments": [
                  {
                      "codes": [
                          "itemSaveForm.quantity",
                          "quantity"
                      ],
                      "arguments"null,
                      "defaultMessage""quantity",
                      "code""quantity"
                  },
                  9999
              ],
              "defaultMessage""9999 이하여야 합니다",
              "objectName""itemSaveForm",
              "field""quantity",
              "rejectedValue"10000,
              "bindingFailure"false,
              "code""Max"
          }
      ]


      3. 검증에 성공

      {"itemName":"hello", "price":1000, "quantity": 1000}​

      응답 메시지 바디

      {
          "itemName""hello",
          "price"1000,
          "quantity"1000
      }

     

    @ModelAttribute와 @RequestBody의 차이

     

    • @ModelAttribute
           - 각각의 필드 단위로 정교하게 바인딩이 적용
           - 필드에 타입이 맞지 않는 오류가 발생해도 나머지 필드는 정상 처리 가능
           - 즉, 특정 필드가 바인딩되지 않아도 나머지 필드는 정상적으로 바인딩, 검증 처리가 가능

    • @RequestBody
           - 필드 단위로 적용되는 것이 아닌 객체 단위로 적용
           - HttpMessageConverter 단계에서 JSON 데이터를 객체로 변경하지 못하면
             컨트롤러를 호출하지 못하므로 예외가 발생

     

    @Valid를 이용하여 @RequestBody 객체 검증 참고 사이트

    SpringBoot API 요청 값 검증하고 Validation Exception Handing하기 (tistory.com)

    @Valid 를 이용해 @RequestBody 객체 검증하기 (tistory.com)

     

     

     

     

     

     

     

     

    반응형

    댓글

Designed by Tistory.