ResponseEntity
HTTP 요청에 대한 응답을 제어하는 데 사용되는 클래스.
ResponseEntity는 Status, Headers, Body를 필드로 갖습니다. 이를 통해 세밀하게 응답을 관리할 수 있습니다. Body를 필드로 가지고 있기 때문에 @RestController 또는 @RequestBody와 함께 사용됩니다.
ResponseEntity<T> responseEntity = new ResponseEntity<>(body, headers, status);
<예시1>
- T: Response Body의 타입
- body: 객체, String, List, Map 등
- headers: HTTP Header
- status: HTTP Response Status Code
ResponseEntity가 생겨난 이유
일반적으로 Controller에서 아래와 같이 객체를 Return 하는 경우 HTTP 응답을 세밀하게 제어할 수가 없습니다.
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class MemoController {
private final MemoService memoService;
@PostMapping("/memos")
public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
return memoService.createMemo(requestDto);
}
}
하지만 ResponseEntity를 사용하면 적절한 상태 코드와 응답 헤더 및 바디를 작성할 수 있습니다.
@PostMapping("/memos")
public ResponseEntity<MemoResponseDto> createMemo(@RequestBody MemoRequestDto requestDto) {
MemoResponseDto memoResponseDto = memoService.createMemo(requestDto);
return ResponseEntity.ok(memoResponseDto);
}
<예시2>
성공을 의미하는 OK(200 code)와 함께 memoResponseDto를 전달할 수 있습니다.
ResponseEntity 사용법
<예시1>과 <예시2>에서 보시다시피 ResponseEntity를 사용하는 방법은 두 가지입니다.
1. 생성자 패턴
@GetMapping("/example")
public ResponseEntity<String> getExampleResponse() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
headers.add("Custom-Header", "CustomValue");
String body = "{\"message\": \"코드에서 냄새가 나네요.(다시 짜세요.)\"}";
return new ResponseEntity<>(body, headers, (HttpStatus.OK));
}
2. 빌더 패턴
빌더 패턴을 사용하는 것이 의미가 더 직관적이고 유지보수에 좋습니다.
header에는 (요청/응답)에 대한 요구사항이, body에는 그 내용이 들어갑니다.
@GetMapping("/example")
public ResponseEntity<String> getExampleResponse() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
headers.add("Custom-Header", "CustomValue");
String body = "{\"message\": \"코드에서 구린내가 나네요.(다시!)\"}";
return ResponseEntity.status(HttpStatus.OK)
.headers(headers)
.body(body);
}
자주 쓰이는 status 값
상태값 | status()의 인자값 | 설명 |
200 | HttpStatus.OK | 요청이 성공적으로 처리된 경우 |
201 | HttpStatus.CREATED | 새로운 리소스가 성공적으로 생성된 경우 |
202 | HttpStatus.ACCEPTED | 처리가 아직 완료되지 않았지만 시작되었음을 클라이언트에 알릴 경우 |
204 | HttpStatus.NO_CONTENT | 주로 삭제 요청이나 업데이트 후 body가 필요 없는 경우 |
300 | HttpStatus.MULTIPLE_CHOICES | 요청에 대해 하나 이상의 응답이 가능한 경우 |
302 | HttpStatus.FOUND | 요청한 리소스의 URI가 일시적으로 변경된 경우 |
400 | HttpStatus.BAD_REQUEST | 잘못된 문법으로 인해 서버가 요청을 이해할 수 없는 경우 |
401 | UNAUTHORIZED | 인증되지 않은 경우 |
404 | HttpStatus.NOT_FOUND | 요청(값)을 찾을 수 없는 경우 |
429 | HttpStatus.TOO_MANY_REQUESTS | 사용자로부터 너무 많은 요청이 발생한 경우 |
500 | HttpStatus.INTERNAL_SERVER_ERROR | 서버에서 에러가 발생한 경우 |
\": 문자열 안에서 큰따옴표(")를 사용하려면 이스케이프 문자(\)를 사용하여야 합니다.
와일드카드
ResponseEntity의 타입을 명시하지 않으면 Object 타입을 Return 해줍니다.
public ResponseEntity getMemo() {...}
public ResponseEntity<Object> getMemo(int id) {...}
따라서 위 두 메서드의 리턴 타입은 같습니다.
하지만 타입을 여러 개 받고 싶다면 와일드카드 <T>를 사용하는 것이 낫습니다.
Object에서 원하는 타입으로 형변환하지 않아도 되기 때문입니다.
public ResponseEntity<T> getMemo() {
T memo = memoService.getMemo();
return ResponseEntity.ok(memo);
}
추가 사항

@ResponseStatus(HttpStatus.BAD_REQUEST)
@PostMapping("/login")
public UserResponseDto login(@RequestBody LoginRequestDto requestDto) {
return userService.login(requestDto);
}
위와 같이 메서드에 @ResponseStatus를 달면 응답을 일부 관리할 수 있으나, 메서드가 실행될 때 항상 400(BAD_REQUEST) 상태 코드로 응답을 반환하게 됩니다.
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class InvalidLoginException extends RuntimeException {
public InvalidLoginException(String message) {
super(message);
}
}
위와 같이 클래스에 @ResponseStatus를 달면 특정 예외가 발생했을 때 해당 상태 코드로 응답을 반환하도록 설정할 수 있습니다.
그리고 서비스나 컨트롤러에서 예외를 던지면 자동으로 400 상태 코드가 응답됩니다.
@PostMapping("/login")
public String login(@RequestBody LoginRequestDto requestDto) {
String result = userService.login(requestDto);
if (result == null) {
throw new InvalidLoginException("아이디 또는 비밀번호를 확인하세요");
}
return result;
}
'Spring > Spring 문법' 카테고리의 다른 글
Spring boot 에서 이메일 인증 구현하기 (googleEmail) - Bean 만들어서 주입하기 (0) | 2024.10.24 |
---|---|
Spring boot 에서 이메일 인증 구현하기 (googleEmail) - JavaMailSender 자동 주입 (2) | 2024.10.24 |
Spring MVC 와 3 Layer Architecture (0) | 2024.10.20 |
API와 HTTP 메서드 (4) | 2024.10.19 |
@PathVariable vs @RequestParam (0) | 2024.10.18 |