정적 리소스는 해당 파일 변경없이 그대로 서비스 하는것으로써
웹 브라우저에서는 정적인 HTML, css, js을 제공할 때 정적 리소스를 사용한다.
src/main/resources
는 리소스를 보관하는 곳이고, 또 클래스패스의 시작 경로이다.src/main/resources/static
src/main/resources/static/basic/hello-form.html
에 있는 파일을 접근할땐http://localhost:8080/basic/hello-form.html
뷰 템플릿을 거쳐서 HTML이 생성되고, 뷰가 응답을 만들어서 전달한다.
일반적으로 HTML을 동적으로 생성하는 용도로 사용하지만, 다른 것들도 가능하다. 뷰 템플릿이 만들 수 있는 것이라면 뭐든지 가능하다.
src/main/resources/templates
@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";
}
보통 2번째 것을 자주 쓴다. 1번째 것은 너무 손이 많이가서..
HTML이나 뷰 템플릿을 사용해도 HTTP 응답 메시지 바디에 HTML 데이터가 담겨서 전달된다.
여기서 설명하는 내용은 정적 리소스나 뷰 템플릿을 거치지 않고 직접! HTTP 응답 메시지를 전달하는 것을 뜻한다.
HttpServletResponse
객체를 통해서 HTTP 메시지 바디에 직접 ok 응답 메시지를 전달한다.response.getWriter().write("ok")
ResponseEnitity
사용return new ResponseEntity<>("ok", HttpStatus.OK);
ResponseBody
사용@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3(){
return "ok";
}
ResponseEntity<>
+ 제네릭에 클래스 타입 @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);
}
위의 방법은 Http status도 상황에 따라 변경 가능하다는 장점이 있다.
JSON
을 보내고 싶다면 @ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
사용이 편리하고 첫 번째 방법과 결과는 동일하지만 HTTP status가 애노테이션에 고정된다는 점이 단점이다.
TIP!
만약@ResponseBody
를 함수마다 붙이기엔 너무 많고 함수가 속해있는 함수 전부 HTTP 메시지 바디에 직접 응답하고 싶다면@RestController
를 클래스 단에 붙여주면 된다.
@ResponseBody
orHttpEntity(ResponseEntity)
사용시 -> HTTP 응답viewResolver
대신에 HttpMessageConverter
가 동작StringHttpMessageConverter
가 작동하고MappingJackson2HttpMessageConverter
가 동작한다.@RequestBody
or HttpEntity(RequestEntity)
사용시 -> HTTP 요청당연히 여러종류의 HTTP메시지 컨버터가 있으니 어떤걸 먼저 쓸지 우선 순위가 있다.
우선순위는 다음과 같다.(이게 전부는 아님)
0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
위의 컨버터가 대표적인 HTTP메시지 컨버터다.
ByteArrayHttpMessageConverter
: byte[]
데이터를 처리한다.byte[]
, 미디어타입: */*
@RequestBody byte[] data
@ResponseBody return byte[]
쓰기 미디어타입 application/octet-stream
StringHttpMessageConverter
: String
문자로 데이터를 처리한다.*/*
@RequestBody String data
@ResponseBody return "ok"
쓰기 미디어타입 text/plain
MappingJackson2HttpMessageConverter
: application/json
HashMap
, 미디어타입 application/json
관련@RequestBody HelloData data
@ResponseBody return helloData
쓰기 미디어타입 application/json
관련*/*
*/*
요약: HTTP 메시지 컨버터가 canWrite나 canRead를 통해 자동으로 해석하여 걸맞는 값을 읽기or 생성을 해준다고 생각하자