반응형
1. ResponseEntity란?
- Spring Framework에는 HTTP Request 혹은 Response을 나타내기 위해 제공하는 HttpEntity라는 클래스가 존재합니다
- HttpEntity는 HttpHeader와 HttpBody를 포함하는 클래스입니다
- 위에서 소개된 HttpEntity를 상속하여 추가적으로 HttpStatus 속성을 더 가지는 클래스가 RequestEntity, ResponseEntity 클래스입니다
- 제네릭으로 선언되어있으며 해당부분은 HttpBody의 타입을 나타냅니다
2. @ResponseStatus란?
- 위에서 소개드린 ResponseEntity를 이용하면 HttpStatus, HttpHeader, HttpBody를 표현할 수 있습니다
- 이 중에서 HttpStatus를 다른 방식으로 표현할 수 있는데 이것이 @ResponseStatus 어노테이션을 통해 마킹하는 방법입니다
- Controller단에서 반환하는 Body를 감싸 @ResponseStatus에 정의된 HttpStatus를 추가할 수도 있지만 주로 예외처리에서 많이 쓰입니다 ( 이유는 사용법에서!! )
3. 사용법
- ResponseEntity
- static method를 활용하여 ResponseEntity 반환
// static method @GetMapping(value = "/my-response/v1/get") public ResponseEntity<String> myV1Get() { return ResponseEntity.ok("hello world!"); }
// response HTTP/1.1 200 Content-Type: text/plain;charset=UTF-8 Content-Length: 12 Date: Sun, 12 Sep 2021 05:26:22 GMT Keep-Alive: timeout=60 Connection: keep-alive hello world!
- ResponseEntity에는 자주 쓰이는 HttpStatus로 쉽게 instance를 생성할 수 있는 static 메서드를 지원합니다
- OK(200), CREATED(201), NO_CONTENT(204), NOT_FOUND(404) 등등
- 생성자를 이용한 ResponseEntity 반환
// constructor @GetMapping(value = "/my-response/v2/get") public ResponseEntity<String> myV2Get() { return new ResponseEntity("hello world!", HttpStatus.OK); }
// response HTTP/1.1 200 Content-Type: text/plain;charset=UTF-8 Content-Length: 12 Date: Sun, 12 Sep 2021 05:31:22 GMT Keep-Alive: timeout=60 Connection: keep-alive hello world!
- 결국 static 메서드로 정의된 내용은 위의 예제처럼 생성자를 통해서 생성할 수 있습니다
- ResponseEntity는 여러 생성자를 지원하며 HttpBody, HttpHeader, HttpStatus 세 가지의 케이스를 유연하게 오버로딩해놨습니다
- HttpHeader 추가하기
// add HttpHeader @GetMapping(value = "/my-response/v3/get") public ResponseEntity<String> myV3Get() { MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); headers.add("test", "hello world!!!!"); return new ResponseEntity("hello world!", headers, HttpStatus.OK); }
// response HTTP/1.1 200 test: hello world!!!! Content-Type: text/plain;charset=UTF-8 Content-Length: 12 Date: Sun, 12 Sep 2021 05:34:32 GMT Keep-Alive: timeout=60 Connection: keep-alive hello world!
- ResponseEntity는 MultiValueMap type을 가지는 Header를 정의할 수 있습니다
- 기본적으로 쓰이는 Header(Content-Type, Accept 등)은 각기 다른 어노테이션등으로 마킹하여 표기하는 것이 일반적이나 커스텀한 Header등을 정의할 때 사용합니다
- static method를 활용하여 ResponseEntity 반환
- @ResponseStatus
- Controller layer 사용
// @ResponseStatus @ResponseStatus(value = HttpStatus.OK) @GetMapping(value = "/my-response/v4/get") public String myV4Get() { return "hello world!"; } @ResponseStatus(value = HttpStatus.CREATED) @GetMapping(value = "/my-response/v5/get") public String myV5Get() { return "hello world!"; }
// HttpStatus.OK response HTTP/1.1 200 Content-Type: text/plain;charset=UTF-8 Content-Length: 12 Date: Sun, 12 Sep 2021 05:46:29 GMT Keep-Alive: timeout=60 Connection: keep-alive hello world! // HttpStatus.CREATED response HTTP/1.1 201 Content-Type: text/plain;charset=UTF-8 Content-Length: 12 Date: Sun, 12 Sep 2021 05:46:32 GMT Keep-Alive: timeout=60 Connection: keep-alive hello world!
- 위 예제는 ModelAndView로 반환하는 @Controller가 아닌 텍스트 Body로 반환하는 @RestController 기준으로 작성되었습니다
- @ResponseStatus에 정의된 HttpStatus로 반환되는 것을 확인할 수 있습니다
- 다만 @ResponseStatus는 위에서 본 ResponseEntity 클래스처럼 유연하지 않습니다, 커스텀 Header 정의도 불가능하며 반환값에 추가적인 작업도 불가능합니다
- @ResponseStatus의 기본 default는 HttpStatus.INTENAL_SERVER_ERROR(500) 입니다
- Exception으로 활용
// Custom Exception @ResponseStatus(value = HttpStatus.NOT_FOUND) @Slf4j public class MyResponseCustomException extends RuntimeException { public MyResponseCustomException(String message) { super(message); log.error(message); } }
- 기본적으로 Spring Web MVC는 로직상에서 Exception이 터지면 HttpStatus.INTERNAL_SERVER_ERROR를 반환합니다
- 위처럼 Exception에 @ResponseStatus를 정의하면 해당 HttpStatus로 반환할 수 있습니다
- @ControllerAdvice로 활용
// @ControllerAdvice @RestControllerAdvice public class MyResponseGlobalExceptionHandler { @ResponseStatus(HttpStatus.NOT_ACCEPTABLE) @ExceptionHandler(MyResponseCustomException.class) public String myResponseCustomExceptionHandler(MyResponseCustomException ex) { return ex.getMessage(); } }
- 위에서 보셧던 예저처럼 Exception에서 정의할 수도 있고, @ControllerAdvice 혹은 @ExceptionHandler에서 활용할 수 도 있습니다
- Controller layer 사용
728x90
반응형
'Tech > Spring' 카테고리의 다른 글
파라미터 바인딩 어노테이션 (0) | 2021.10.27 |
---|---|
Spring Framework에서 자주 쓰는 어노테이션 개념 정리 (0) | 2021.08.08 |
CORS.. 많이 듣긴했는데... (0) | 2021.08.08 |
Spring Transactional 어디까지 알고있니? (3) | 2021.08.08 |
SpringBoot를 우아하게(?) 종료시켜보자 (1) | 2021.08.08 |