Anyway

[Spring] @RequestBody가 쓰이지 않는 경우 본문

Java/Spring

[Spring] @RequestBody가 쓰이지 않는 경우

dyana 2024. 8. 28. 13:50

코드 개발을 하던 중

 

1️⃣

    public CommonResult update(@RequestBody @Valid DeptUpdateReqDto deptUpdateReqDto,
                               BindingResult bindingResult) throws ApiBindException  {
        if (bindingResult.hasErrors()) {
            throw new ApiBindException(bindingResult);
        }

        deptService.update(deptUpdateReqDto);
        // 보여줄 데이터가 있는 게 아니니깐 성공시 ok() 소환 > SUCCESS(code랑 메세지만 들어가 있는거)
        return CommonResult.ok();
    }

 

➡️ 해당 코드에서는 @RequestBody로 dto를 받아 유효성 검증 후 .. 돌아가는데

 

2️⃣

    public CommonResult login(@Valid LoginReqDto dto, BindingResult bindingResult) throws ApiBindException{
        if (bindingResult.hasErrors()) {
            throw new ApiBindException(bindingResult);
        }
        return memberService.login(dto);
    }

 

➡️ 이 코드의 경우는 왜 @RequestBody를 쓰지 않았는지 어떤 차이가 있는지 이해할 필요가 있었다. 

 

@RequestBody가 사용되지 않는 이유는 코드의 컨텍스트에 따라 다르지만 일반적으로 @RequestBody가 필요하지 않은 몇 가지 시나리오가 있다.

 

  1. Form 데이터를 받을 때
    만약 클라이언트가 데이터를 application/x-www-form-urlencoded나 multipert/form-data 같은 형식으로 전송하고 있다면 spring MVC는 요청 본문에서 데이터를 추출할 때 @RequestBody 대신 단순히 메소드 파라미터로 바인딩 할 수 있다. 이 경우 @Valid와 BindingResult를 사용해 입력값 검증을 할 수 있다. (두 번째 코드 예제처럼)
  2. URL 쿼리 파라미터나 경로 변수 사용
    요청 데이터가 URL 쿼리 파라미터나 경로 변수로 전달된다면 @RequestBody는 필요하지 않다.
    이 경우 Spirng은 메소드파라미터를 자동으로 바인딩 한다.
  3. 기본적으로 지원되는 데이터 형식
    만약 @Valid로 검증할 데이터가 자바 빈 객체로 표현될 수 있는 경우 Spring은 자동으로 요청 매개변수를 DTO 객체에 바인딩 할 수 있다. 이 경우에도 @RequestBody는 필요하지 않다. 
  4. 요청 데이터가 JSON이나 XML이 아닌 경우
    @RequestBody는 주로 JSON이나 XML 데이터를 자바 객체로 변환하는 데 사용된다. 만약 요청 데이터가 이러한 형식이 아니고 단순한 폼 데이터이거나 URL 인코딩된 데이터라면 @RequestBody가 필요하지 않다. 

따라서 두 번째 코드에서 @RequestBody가 사용되지 않은 이유는 파라미터로 전달되기 때문이다. 

요청이 JSON 형식으로 전달되는 첫 번째 코드와 같은 경우 @RequestBody를 사용해야 JSON을 DTO 객체로 변환할 수 있다. 

즉 1️⃣번 코드의 경우 @RequestBody 어노테이션은 클라이언트가 요청 본문에 JSON, XML 등으로 보내는 데이터를 DeptUpdateReqDto 객체에 매핑하는 역할을 한다. 만약 이 어노테이션을 제거하면 Spring이 요청 본문을 읽지 않고 DeptUpdateReqDto 객체를 생성할 수 없다. 

 

2️⃣번 코드의 경우는 클라이언트로부터 파라미터를 받아 생략된 @ModelAttribute에 의해 값이 들어가고 쓰일 수 있게 된다.