Handler Method : ResponseEntity
2024. 10. 9. 16:58ㆍSpring Framework/Web on Servlet Stack
ResponseEntity는 HTTP 응답 본문, 상태 코드, 그리고 응답 헤더를 함께 처리할 수 있는 스프링의 강력한 기능입니다. @ResponseBody는 주로 응답 본문만 직렬화하여 반환하는 반면, ResponseEntity는 상태 코드와 헤더를 포함한 더 많은 정보를 제어할 수 있습니다.
기본 개념
- ResponseEntity는 HTTP 응답의 상태 코드와 헤더를 포함하여 응답을 더 세부적으로 제어할 수 있습니다. 예를 들어, 응답의 HTTP 상태 코드, ETag(헤더), 응답 본문 등을 함께 설정할 수 있습니다.
- 본문: 응답의 내용, 보통 JSON, XML, 문자열 등의 데이터를 포함할 수 있습니다.
- 헤더: 응답에 포함될 다양한 HTTP 헤더를 설정할 수 있습니다. 예를 들어,
ETag
,Cache-Control
등을 설정할 수 있습니다. - 상태 코드:
200 OK
,404 Not Found
,500 Internal Server Error
와 같은 HTTP 상태 코드를 지정할 수 있습니다.
ResponseEntity
사용 예시
1. 문자열 응답과 상태 코드, 헤더 설정
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExampleController {
@GetMapping("/something")
public ResponseEntity<String> handle() {
String body = "This is the response body";
String etag = "12345"; // 예를 들어 ETag 값
// 200 OK 상태와 함께 응답 본문과 ETag 헤더 반환
return ResponseEntity.ok()
.eTag(etag)
.body(body);
}
}
코드 설명:
- ResponseEntity.ok():
200 OK
상태 코드를 설정합니다. - eTag(etag): 응답 헤더에
ETag
값을 추가합니다. - body(body): 응답 본문으로 문자열을 설정합니다. 이 경우
"This is the response body"
가 클라이언트에 전송됩니다.
2. JSON 객체 응답 예시
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AccountController {
@GetMapping("/accounts/{id}")
public ResponseEntity<Account> getAccount(@PathVariable String id) {
Account account = new Account(id, "John Doe", 1000);
// 200 OK 상태와 함께 Account 객체를 JSON으로 반환
return ResponseEntity.ok(account);
}
}
코드 설명:
- ResponseEntity.ok(account):
Account
객체를 JSON으로 변환하여 반환합니다.HttpMessageConverter
가 이를 JSON으로 직렬화하여 클라이언트로 전달합니다.
파일 콘텐츠 응답
파일을 응답으로 전송할 때는 Resource 객체를 ResponseEntity
와 함께 사용하여 InputStream을 클라이언트에 전달할 수 있습니다.
파일 다운로드 예시
import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FileController {
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile() {
// 클래스 경로에 있는 파일을 리소스로 반환
Resource file = new ClassPathResource("files/example.txt");
// 파일 다운로드 응답 설정
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=example.txt")
.contentType(MediaType.TEXT_PLAIN)
.body(file);
}
}
코드 설명:
- Resource: 파일을
Resource
객체로 반환하여 응답 본문에 스트리밍합니다. - CONTENT_DISPOSITION: 이 헤더를 통해 클라이언트가 파일을 다운로드하도록 설정합니다. 파일 이름을
example.txt
로 지정했습니다. - contentType(): 응답의 콘텐츠 타입을
text/plain
으로 설정합니다.
비동기 응답 (Reactive 스택에서 ResponseEntity
사용)
Spring WebFlux와 같은 비동기 스택에서는 Mono 또는 Flux와 함께 ResponseEntity
를 사용하여 비동기 응답을 처리할 수 있습니다.
WebFlux에서 Mono<ResponseEntity>
사용 예시
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
public class ReactiveAccountController {
@GetMapping("/accounts/{id}")
public Mono<ResponseEntity<Account>> getAccount(@PathVariable String id) {
Account account = new Account(id, "John Doe", 1000);
// 비동기적으로 ResponseEntity와 Account 객체 반환
return Mono.just(ResponseEntity.ok(account));
}
}
코드 설명:
- Mono<ResponseEntity>: 비동기적으로
Account
객체와 상태 코드를 포함한ResponseEntity
를 반환합니다. - Mono.just(): 비동기 응답을 반환하며, 클라이언트는 응답을 기다렸다가
Account
객체와 함께 응답을 받게 됩니다.
비동기 응답에서 상태 코드와 본문을 동시에 처리
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
public class ReactiveAccountController {
@GetMapping("/accounts/{id}")
public Mono<ResponseEntity<Account>> getAccount(@PathVariable String id) {
return findAccountById(id)
.map(account -> ResponseEntity.ok(account)) // 200 OK와 함께 Account 반환
.defaultIfEmpty(ResponseEntity.notFound().build()); // 없을 경우 404 반환
}
private Mono<Account> findAccountById(String id) {
// 가상의 비동기 데이터베이스 조회
Account account = new Account(id, "John Doe", 1000);
return Mono.just(account);
}
}
코드 설명:
- map(account -> ResponseEntity.ok(account)): 비동기적으로 데이터를 조회하여 200 OK 응답과 함께
Account
객체를 반환합니다. - defaultIfEmpty(): 데이터가 없을 경우 404 Not Found 응답을 반환합니다.
요약
- ResponseEntity는 HTTP 상태 코드, 응답 본문, 헤더를 모두 제어할 수 있는 객체입니다. 이를 통해 클라이언트에게 더 세부적인 응답을 보낼 수 있습니다.
- ResponseEntity.ok(): 주로 200 OK 상태 코드를 반환하며, 본문과 헤더를 함께 설정할 수 있습니다.
- 파일 응답:
Resource
객체를 사용하여 파일을 클라이언트로 스트리밍할 수 있으며,CONTENT_DISPOSITION
헤더를 설정해 파일 다운로드를 유도할 수 있습니다. - Reactive 스택에서는
Mono
와ResponseEntity
를 결합하여 비동기적으로 응답을 처리할 수 있습니다.
이 방식은 클라이언트에게 상태 코드와 헤더를 포함한 응답을 보낼 수 있는 매우 유연한 방법으로, RESTful API 설계에서 주로 사용됩니다.
'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글
Model (0) | 2024.10.09 |
---|---|
Handler Method : Jackson JSON (0) | 2024.10.09 |
Handler Method : @ResponseBody (0) | 2024.10.09 |
Handler Method : HttpEntity (0) | 2024.10.09 |
Handler Mapping : @RequestBody (0) | 2024.10.09 |