Handler Method : @ResponseBody

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


@ResponseBody 어노테이션은 컨트롤러 메서드의 반환값을 HTTP 응답 본문으로 직접 변환하여 클라이언트로 전달하는 역할을 합니다. HttpMessageConverter를 통해 반환 객체는 JSON, XML 등의 형식으로 자동으로 변환됩니다. 주로 RESTful API에서 데이터를 반환할 때 사용됩니다.

기본 개념

  • @ResponseBody: 메서드의 반환값을 응답 본문으로 직렬화하여 클라이언트에게 전송합니다. 반환된 객체는 스프링의 HttpMessageConverter를 통해 JSON이나 XML 등의 형식으로 변환되어 클라이언트로 전달됩니다.
  • @RestController: @Controller@ResponseBody가 결합된 메타 어노테이션으로, 클래스에 선언되면 해당 클래스의 모든 메서드에서 @ResponseBody가 자동으로 적용됩니다. 이를 통해 각 메서드마다 @ResponseBody를 따로 선언할 필요가 없습니다.

@ResponseBody 사용 예시

1. 기본 사용 예시

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.stereotype.Controller;

@Controller
public class AccountController {

    @GetMapping("/accounts/{id}")
    @ResponseBody
    public Account handle() {
        // 가상의 Account 객체 반환
        return new Account("John Doe", 1000);
    }
}

코드 설명:

  • @ResponseBody: 이 메서드는 반환값을 응답 본문으로 직렬화하여 클라이언트에게 전달합니다. 예를 들어, Account 객체가 반환되면 JSON 형식으로 변환되어 응답됩니다.

  • HttpMessageConverter: 반환된 Account 객체는 MappingJackson2HttpMessageConverter를 통해 JSON으로 변환됩니다. 클라이언트는 아래와 같은 JSON 응답을 받습니다.

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

2. @RestController 사용

@ResponseBody를 클래스 수준에서 적용하려면 @RestController를 사용할 수 있습니다. @RestController@Controller@ResponseBody를 결합한 메타 어노테이션으로, 클래스 내의 모든 메서드에 자동으로 @ResponseBody를 적용합니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AccountController {

    @GetMapping("/accounts/{id}")
    public Account handle() {
        // 가상의 Account 객체 반환
        return new Account("John Doe", 1000);
    }
}

코드 설명:

  • @RestController: 클래스에 선언되면, 모든 메서드가 자동으로 @ResponseBody 기능을 적용받습니다. @ResponseBody를 메서드마다 명시적으로 선언할 필요가 없습니다.

파일 컨텐츠 반환 (Resource 객체 사용)

파일을 응답 본문으로 반환할 때는 Resource 객체를 사용할 수 있습니다. 이를 통해 파일을 클라이언트로 스트리밍하거나 다운로드할 수 있습니다. InputStream을 사용해 파일 내용을 응답 스트림에 복사하여 처리합니다.

파일 다운로드 예시

import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.stereotype.Controller;

@Controller
public class FileController {

    @GetMapping("/download")
    @ResponseBody
    public Resource downloadFile() {
        // 클래스 경로에 있는 파일을 리소스로 반환
        return new ClassPathResource("files/example.txt");
    }
}

코드 설명:

  • Resource: 파일을 클라이언트에 전송할 때 Resource 객체를 사용합니다. 여기서는 클래스 경로에 있는 파일을 ClassPathResource로 반환합니다.
  • 파일 스트리밍: 클라이언트는 example.txt 파일을 다운로드할 수 있으며, 파일은 서버의 InputStream을 통해 스트리밍됩니다.

@ResponseBody와 유효성 검사

@RequestBody와 마찬가지로, @ResponseBody를 사용할 때도 유효성 검사를 적용할 수 있습니다. 반환하는 객체에 대해 검증을 수행할 수 있으며, 검증 오류가 발생하면 스프링은 자동으로 400 (Bad Request) 응답을 보냅니다.

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

Spring WebFlux에서는 비동기적으로 데이터를 처리하기 때문에, 메서드의 반환 타입으로 Mono 또는 Flux를 사용하여 비동기 응답을 처리합니다.

WebFlux에서 Mono를 사용한 예시

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

@RestController
public class ReactiveAccountController {

    @GetMapping("/accounts/{id}")
    public Mono<Account> getAccount() {
        // 비동기적으로 Account 객체 반환
        return Mono.just(new Account("John Doe", 1000));
    }
}

코드 설명:

  • Mono<Account>: WebFlux에서는 비동기 데이터를 처리하기 위해 Mono를 사용합니다. Mono는 0 또는 1개의 값을 비동기적으로 반환하는 객체입니다.
  • JSON 직렬화: Mono로 반환된 Account 객체는 자동으로 JSON 형식으로 직렬화되어 클라이언트에 응답됩니다.

Message Converters 설정

스프링에서 응답 본문을 변환할 때 사용하는 HttpMessageConverter는 기본적으로 JSON 처리를 위한 MappingJackson2HttpMessageConverter를 사용합니다. 하지만, XML이나 다른 형식으로 데이터를 반환하고 싶다면 Message Converters를 커스터마이징할 수 있습니다.

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());
        // 다른 형식의 Message Converter 추가 가능
    }
}

요약

  • @ResponseBody는 컨트롤러 메서드의 반환값을 응답 본문으로 직렬화하여 클라이언트에 전달합니다. 스프링의 HttpMessageConverter를 통해 객체는 JSON 또는 XML 등으로 변환됩니다.
  • @RestController@ResponseBody를 클래스 수준에서 적용한 것으로, 모든 메서드에 자동으로 응답 본문 직렬화를 적용합니다.
  • 파일이나 다른 리소스를 응답으로 반환할 때는 Resource 객체를 사용하여 파일을 스트리밍하거나 다운로드할 수 있습니다.
  • Spring WebFlux에서는 Mono 또는 Flux를 사용하여 비동기적으로 데이터를 처리하며, 반환된 객체는 자동으로 JSON으로 직렬화됩니다.

이 방식은 RESTful API에서 데이터를 간단하게 응답으로 처리하고 클라이언트에게 전달하는 데 매우 유용합니다.


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

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

Handler Method : Jackson JSON  (0) 2024.10.09
Handler Method : ResponseEntity  (1) 2024.10.09
Handler Method : HttpEntity  (0) 2024.10.09
Handler Mapping : @RequestBody  (0) 2024.10.09
Handler Method : Multipart  (0) 2024.10.09