/static
, /public
, /resources
, /META-INF/resources
에 위치하며 여기에 있는 파일은 스프링 부트가 뜨면서 정적리소스로 톰캣을 통해 서빙한다.@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
ModelAndView mav = new ModelAndView("response/hello")
.addObject("data", "hello!");
return mav;
}
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
model.addAttribute("data", "hello!!");
return "response/hello";
}
classpath:/templates/
을 suffix는 .html
을 제공한다.@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
model.addAttribute("data", "hello!!");
}
얘는 별로 권장하진 않음 컨트롤로 이름이 path로 되어있을 경우 spring이 컨벤션하게 그냥 찾아서 보내준다는 것인데 직관적이지 않기 때문에 탈락!
보면 전체적으로 @ResponseBody가 없기 때문에 view resolver가 view를 찾아서 렌더링하고있다.
그리고 만약 @ResponseBody가 명시되어있다면 그냥 body에 'response/hello' 예시처럼 경로를 적어서 보내면 된다.
@ResponseBody , HttpEntity 를 사용하면, 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 응답
데이터를 출력할 수 있다.
나중에 다시 포스팅하겠지만 일단 가볍게 적고가자면 타임리프를 추가하면 스프링 부트가 자동으로 ThymeleafViewResolver 와 필요한 스프링 빈들을 등록한다. 그리고 앞서도 언급했듯 prefix와 suffix를 설정해주는 이 설정은 기본 값 이기 때문에 변경이 필요할 때만 설정하면 된다.
더 자세한 옵션들은 공식 문서를 보면 된다.
@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException
{
response.getWriter().write("ok");
}
/**
* HttpEntity, ResponseEntity(Http Status 추가)
* @return
*/
@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
return new ResponseEntity<>("ok", HttpStatus.OK);
}
@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "ok";
}
@GetMapping("/response-body-json-v1")
public ResponseEntity<HelloData> responseBodyJsonV1() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return new ResponseEntity<>(helloData, HttpStatus.OK);
}
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
@ResponseBody 어노테이션을 붙이면 귀찮게 ResponseEntity를 추가하여 제네릭 타입을 안 잡아줘도 된다. 다만 이렇게 되면 상태 코드를 응답할 수 없기에
@ResponseStatus 어노테이션을 추가하여 상태코드를 잡아줄 수 있다.
다만 단점은 동적으로 반환이 안 되서 동적으로 상태코드를 응답하고 싶다면 ResponseEntity를 사용해야한다.
@Controller 대신에 @RestController 애노테이션을 사용하면, 해당 컨트롤러에 모두 @ResponseBody 가 적용되는 효과가 있다. 따라서 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 데이터를 입력한다.
참고로 @ResponseBody 는 클래스 레벨에 두면 전체 메서드에 적용되는데, @RestController 에노테이션 안에 @ResponseBody 가 적용되어 있다.
그래서 아래는 @RestController와 함께 개발자가 가장 많이 사용하는 방식이다.
@ResponseStatus(HttpStatus.OK)
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}