Handler Mapping : @RequestBody

2024. 10. 9. 16:44Spring Framework/Web on Servlet Stack


`@RequestBody` 어노테이션은 **HTTP 요청의 본문(Request Body)**을 읽어와서 이를 **Java 객체로 역직렬화**(deserialization)하는 데 사용됩니다. 스프링에서는 **HttpMessageConverter**를 통해 요청 본문을 자동으로 처리하며, JSON이나 XML 형식의 데이터를 객체로 변환할 수 있습니다. 이 어노테이션은 주로 **RESTful API**에서 클라이언트로부터 데이터를 받아 처리할 때 사용됩니다.

기본 개념

  • @RequestBody: HTTP 요청의 본문에 있는 데이터를 지정된 객체로 변환하여 컨트롤러 메서드의 아규먼트로 전달합니다. 일반적으로 JSON 형식의 데이터를 Java 객체로 변환하는 데 사용되며, 스프링이 제공하는 HttpMessageConverter가 이 작업을 처리합니다.
  • HttpMessageConverter: 스프링이 제공하는 메시지 변환기(Message Converter)로, 요청의 본문을 읽고 이를 Java 객체로 변환하거나, 응답 객체를 특정 형식으로 변환하여 클라이언트에 보낼 수 있도록 합니다.
  • 유효성 검사: @RequestBody@Valid 또는 @Validated 어노테이션과 함께 사용할 수 있으며, 이를 통해 입력된 데이터의 유효성을 검사할 수 있습니다.

주의사항

  • 폼 데이터@RequestBody가 아닌 @RequestParam을 사용하여 처리해야 합니다. 이유는 서블릿 API에서는 요청 파라미터에 접근하는 순간 요청 본문이 파싱되므로, @RequestBody로 다시 본문을 읽을 수 없기 때문입니다.

예시 코드: @RequestBody를 사용한 요청 처리

1. 기본 사용 예시

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.stereotype.Controller;

@Controller
public class AccountController {

    @PostMapping("/accounts")
    public void handle(@RequestBody Account account) {
        // Account 객체 처리 로직
        System.out.println("Account Name: " + account.getName());
    }
}

코드 설명:

  • @RequestBody: 요청 본문에 있는 JSON 데이터를 Account 객체로 변환합니다. 예를 들어, 클라이언트가 아래와 같은 JSON 데이터를 전송하면:

    {
        "name": "John Doe",
        "balance": 1000
    }

    이 데이터는 Account 객체로 변환됩니다.

2. 유효성 검사를 추가한 예시

유효성 검사를 수행하려면 @Valid 어노테이션을 사용하여 입력 데이터를 검사할 수 있습니다. 입력 데이터에 오류가 있는 경우, 400 (Bad Request) 응답이 반환됩니다.

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import jakarta.validation.Valid;
import org.springframework.validation.Errors;
import org.springframework.stereotype.Controller;

@Controller
public class AccountController {

    @PostMapping("/accounts")
    public void handle(@Valid @RequestBody Account account, Errors errors) {
        if (errors.hasErrors()) {
            // 유효성 검사 실패 처리 로직
            System.out.println("Validation failed: " + errors);
            return;
        }
        // Account 객체 처리 로직
        System.out.println("Account Name: " + account.getName());
    }
}

코드 설명:

  • @Valid: Account 객체의 필드에 대해 유효성 검사를 수행합니다. 이 객체는 일반적으로 @NotNull, @Size와 같은 제약 조건을 가질 수 있습니다.
  • Errors: 유효성 검사에서 발생한 오류 정보를 처리하는 아규먼트로, 오류가 있을 경우 오류 메시지를 출력하거나 다른 처리를 할 수 있습니다.

유효성 검사 실패 시 발생하는 400 에러

만약 유효성 검사를 추가하지 않거나, 유효성 검사에 실패하면 스프링은 자동으로 400 Bad Request 응답을 반환합니다. 하지만, Errors 객체를 사용하면 400 응답을 반환하기 전에 컨트롤러 내에서 직접 오류를 처리할 수 있습니다.

HttpMessageConverter를 활용한 커스터마이징

스프링에서는 Message Converters를 사용해 요청 본문을 처리합니다. 기본적으로는 MappingJackson2HttpMessageConverter를 사용해 JSON을 객체로 변환하지만, 필요에 따라 다른 형식(예: XML)으로 변환할 수 있습니다.

Message Converter 설정

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter());
        // 추가적인 메시지 컨버터 설정 가능
    }
}

코드 설명:

  • MappingJackson2HttpMessageConverter: 스프링은 기본적으로 JSON을 처리하는 컨버터로 Jackson 라이브러리를 사용합니다. 다른 형식의 데이터를 처리하려면 메시지 컨버터를 추가하거나 커스터마이징할 수 있습니다.

@RequestBody와 @RequestPart의 차이

  • @RequestBody: 요청 본문 전체를 읽어와 객체로 변환합니다. 주로 JSON, XML 같은 구조화된 데이터 형식에 사용됩니다.
  • @RequestPart: multipart/form-data 요청에서 JSON과 파일 같은 데이터를 동시에 처리할 때 사용됩니다. JSON 데이터를 객체로 변환하고 파일은 MultipartFile로 처리할 수 있습니다.

Reactive 스택에서의 @RequestBody 사용 (Spring WebFlux)

Spring WebFlux에서도 @RequestBody를 사용할 수 있지만, WebFlux는 비동기 방식으로 동작하므로 Mono 또는 Flux 타입을 사용하여 데이터를 처리합니다.

WebFlux 예시 코드

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class AccountController {

    @PostMapping("/accounts")
    public Mono<Void> handle(@RequestBody Mono<Account> accountMono) {
        return accountMono.doOnNext(account -> {
            // Account 객체 처리 로직
            System.out.println("Account Name: " + account.getName());
        }).then();
    }
}

코드 설명:

  • Mono: WebFlux에서는 비동기 요청을 처리하기 위해 Mono 또는 Flux 타입을 사용합니다. Mono<Account>는 하나의 Account 객체를 비동기적으로 반환합니다.
  • doOnNext: Mono가 완료되었을 때 실행할 작업을 정의합니다.

요약

  • @RequestBody는 요청 본문을 객체로 변환하는 데 사용되며, 주로 RESTful API에서 사용됩니다.
  • JSON 데이터를 받아 처리할 때 스프링의 HttpMessageConverter가 이를 자동으로 객체로 변환합니다.
  • 유효성 검사를 위해 @ValidErrors를 사용하여 입력 데이터를 검증할 수 있습니다.
  • Reactive 스택(Spring WebFlux)에서는 Mono 또는 Flux를 사용하여 비동기 방식으로 요청 본문을 처리할 수 있습니다.

이 방식은 클라이언트가 JSON, XML 등의 데이터를 전송할 때 매우 유용하며, 유효성 검사를 통해 안전한 데이터 처리도 가능합니다.


참고 : [https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/requestbody.html](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/requestbody.html)

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

Handler Method : @ResponseBody  (0) 2024.10.09
Handler Method : HttpEntity  (0) 2024.10.09
Handler Method : Multipart  (0) 2024.10.09
Handler Method : Flash Attributes  (0) 2024.10.09
Handler Method : Redirect Attributes  (0) 2024.10.09