- 스프링(서버)에서 응답 데이터를 만드는 방법은 크게 3가지이다.
- 정적 리소스
웹 브라우저에 정적인 HTML, css, js를 제공할 때는, 정적 리소스를 사용한다.
- 뷰 템플릿 사용
웹 브라우저에 동적인 HTML을 제공할 때는 뷰 템플릿을 사용한다.
- HTTP 메시지 사용
HTTP API를 제공하는 경우에는 HTML이 아니라 데이터를 전달해야 하므로, HTTP 메시지 바디에
JSON 같은 형식으로 데이터를 실어 보낸다.
1. 뷰 템플릿 사용
- 먼저 뷰 템플릿을 반환하는 컨트롤러를 작성해보자
@Controller
public class ResponseViewController {
// 1. ModelAndView 반환
@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
ModelAndView mav = new ModelAndView("response/hello")
.addObject("data", "hello!");
return mav;
}
// 2. 문자열 반환
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
model.addAttribute("data", "hello!");
return "response/hello";
}
// 3. void 사용
@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
model.addAttribute("data", "hello!");
}
}
- ModelAndView
ModelAndView를 사용하여 뷰 템플릿의 위치와 Model에 넣은 데이터를 입력하고 ModelAndView를 반환하면 지정된 위치의 뷰 템플릿을 띄워준다.
- 문자열 반환
Model을 매개변수로 받아 데이터를 입력하고, return값으로 문자열을 반환하면 resources/templates에서 문자열과 일치하는 뷰를 찾아 반환한다.
- void 사용
리턴 타입을 void로 설정하고, 뷰의 위치와 url을 일치시키면 해당 뷰를 찾아서 반환해준다. 코드가 조금 줄어들 수는 있지만 명시적으로 드러나지 않기 때문에 비추천한다.
2. HTTP 메시지 사용
- HTTP 메시지 바디에 JSON 같은 형식으로 데이터를 실어 보는 방법
- 뷰 템플릿이나 정적 리소스도 HTTP 바디에 담겨 전달되지만 여기서 말하는 방법은 직접 http바디에 데이터를 담아 전달하는 방법을 말한다.
- 코드로 확인해보자
@Controller
//@ResponseBody
//@RestController
public class ResponseBodyController {
// 1. response객체 활용
@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException {
response.getWriter().write("ok");
}
// 2. ResponseEntity 활용
@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
return new ResponseEntity<>("ok", HttpStatus.OK);
}
// 3. @ResponseBody 활용
@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "ok";
}
// 4. ResponseEntity로 json 데이터 보내기
@GetMapping("/response-body-json-v1")
public ResponseEntity<HelloData> responseBodyJsonV1() throws IOException {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return new ResponseEntity<>(helloData, HttpStatus.OK);
}
// 5. ResponseBody로 json 데이터 보내기
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() throws IOException {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
}
- response객체 활용
response객체에서 writer를 가져와 데이터를 전송하는 방법
- ResponseEntity 활용
ResponseEntity를 활용하면 @ResponseBody를 사용하지 않아도 데이터를 전송할 수 있다
- @ResponseBody 활용
@ResponseBody로 뷰 템플릿이 아닌 데이터를 전송할 수 있음
- ResponseEntity로 json 데이터 보내기
return 값으로 ResponseEntity를 보내면 json형식으로 데이터를 전송할 수 있다.
- ResponseEntity에 상태코드를 담아서 보낼 수 있기 때문에 조건에 따라 다른 상태코드를 유연하게 바꿔 보낼 수 있다.
- @ResponseBody로 객체 보내기
@ResponseBody를 활용하여 리턴값으로 객체를 담아 보내면 json형식으로 데이터를 전송할 수 있다. 또 @ResponseStatus를 이용하면 상태 코드도 함께 보낼 수 있다. 다만 @ResponseStatus는 메서드 단위로 사용되기 때문에 조건에 따라 다른 상태코드를 보내야 한다면 ResponseEntity를 사용해야 한다.
@RestController
- @ResponseBody를 클래스 단위로 붙이면 모든 메서드에 @ResponseBody가 적용되는데, @ResponseBody와 @Controller를 함께 지원하는게 @RestController이다.