일반적으로 @Controller 에서 아래와 같이 뷰 없이 객체만을 return 하는 경우, HTTP 응답을 제어할 수 없다. 아래 코드는 게시글 작성 코드이다. 클라이언트의 post 요청에 대해 board 객체로 응답할 경우 게시글은 정상적으로 db에 저장되지만 클라이언트가 기대하는 HttpStatus(200, 404, 500 등)를 설정해 줄 수 없기 때문에 에러가 발생한다.
*@RestController의 경우엔 기본적으로 http 응답 코드 200이 사용되기 때문에 굳이 ResponseEntity 를 사용해서 따로 http 응답 설정을 안해줘도 된다.
@Controller
@CrossOrigin("http://localhost:3000")
public class BoardController {
private final BoardRepo boardRepo;
public BoardController(BoardRepo boardRepo) {
this.boardRepo = boardRepo;
}
...
@PostMapping("/board/write")
public Board writeBoard(@RequestParam("title") String title, @RequestParam("content") String content){
Board board = new Board();
board.setUsername(SecurityContextHolder.getContext().getAuthentication().getName());
board.setTitle(title);
board.setContent(content);
board.setCreatedDate(new Date());
board.setModifiedDate(new Date());
boardRepo.save(board);
return board;
}
}
따라서 클라이언트와 서버간의 통신에 필요한 정보를 제공해야 한다. 이때 ResponseEntity를 사용하여 적절한 상태 코드와 응답 헤더, 응답 본문을 생성해서 클라이언트에게 전달할 수 있다.
ResponseEntity 를 이해하기 전에 HttpEntity 클래스를 먼저 이해해야 한다. HttpEntity 는 스프링에서 제공하는 클래스로 HTTP 요청 또는 응답 엔티티이다. HttpEntity 는 headers 와 body 로 구성되어 있다.
HttpEntity
public class HttpEntity<T> {
private final HttpHeaders headers;
@Nullable
private final T body;
ReponseEntity 클래스는 HttpEntity 클래스를 상속받는다. 그리고 필드로는 Http 상태 코드를 가진다. 따라서 ResponseEntity 를 이용하면 httpStatus, headers, body 를 전달할 수 있다.
headers는 따로 추가하지 않아도 기본 헤더 값들이 자동으로 포함된다. 따라서 커스텀 헤더를 추가할때 사용한다.
ResponseEntity
public class ResponseEntity<T> extends HttpEntity<T> {
private final HttpStatusCode status;
}
위에서 살펴본 예시를 ResponseEntity를 사용하여 수정해보자.
@Controller
@CrossOrigin("http://localhost:3000")
public class BoardController {
private final BoardRepo boardRepo;
public BoardController(BoardRepo boardRepo) {
this.boardRepo = boardRepo;
}
...
@PostMapping("/board/write")
public ResponseEntity<Object> writeBoard(@RequestParam("title") String title, @RequestParam("content") String content){
Board board = new Board();
board.setUsername(SecurityContextHolder.getContext().getAuthentication().getName());
board.setTitle(title);
board.setContent(content);
board.setCreatedDate(new Date());
board.setModifiedDate(new Date());
HttpHeaders headers = new HttpHeaders();
headers.add("X-Custom-Header", "Value");
return ResponseEntity.ok().headers(headers).body(board);//httpStatus, headers, body
}
}
다음과 같이 클라이언트에게 정상적인 httpStatus, headers, body가 전달된 것을 확인할 수 있다.
body 부분
headers 부분
ResponseEntity 의 메서드에서 httpStatus, body를 설정하는 방식은 두가지가 존재한다.
방법1
httpStatus와 body를 하나의 메서드로 설정, 하지만 이 방식으론 한번에 헤더를 추가할 수 없다. 따라서 헤더를 추가할 필요가 없을 경우에만 사용하는게 좋다.
예시)
ResponseEntity.ok(users)
.header("Custom-Header", "Value")
.body(users);
방법2(추천)
httpStatus와 body를 각각 다른 메서드로 설정한다.
ResponseEntity.ok()
.header("Custom-Header", "Value")
.body(users);