1) 정적 리소스, 뷰 템플릿
스프링에서 응답 데이터를 만드는 방법은 3가지다.
웹 브라우저에 정적인 HTML, css, js를 제공할 때는, 정적 리소스를 사용한다.
웹 브라우저에 동적인 HTML을 제공할 때는 뷰 템플릿을 사용한다.
HTTP API를 제공하는 경우에는 HTML이 아니라 데이터를 전달해야 하므로, HTTP 메시지 바디에 JSON 같은 형식으로 데이터를 실어 보낸다.
/static , /public , /resources , /META-INF/resources 에 있는 리소스는 스프링 부트가 정적으로 제공한다.
뷰 템플릿을 거쳐서 HTML이 생성되고, 뷰가 응답을 만들어서 전달한다.
뷰 템플릿은 일반적으로 html을 동적으로 생성하는 용도지만 다른 것도 가능하다.
"src/main/resources/templates"는 스프링 부트의 기본 템플릿 경로다.
empty
)2) HTTP 응답 - HTTP API, 메세지 바디에 직접 입력
ResponseEntity 는 HTTP 응답 코드를 설정할 수 있는데, @ResponseBody 를 사용하면 이런 것을 설정하기 까다롭다.
@ResponseStatus(HttpStatus.OK) 애노테이션을 사용하면 응답 코드도 설정할 수 있다.
@Restcontroller: @Controller 대신에 @RestController 애노테이션을 사용하면, 해당 컨트롤러에 모두 @ResponseBody 가 적용되는 효과가 있다. 따라서 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 데이터를 입력한다. 이름 그대로 Rest API(HTTP API)를 만들 때 사용하는 컨트롤러이다.
3) HTTP 메시지 컨버터
뷰 템플릿처럼 html을 동적으로 생성해 응답하는 것이 아닌 JSON 데이터를 http 메시지 바디에 직접 읽거나 쓰는 경우 Http 메시지 컨버터를 사용하면 편리하다.
@ResponseBody는 HTTP 바디에 문자 내용을 직접 반환한다.
스프링 mvc는 http 요청의 경우에는 @RequestBody, 응답의 경우에는 @ResponseBody의 경우에 http 메시지 컨버터를 적용한다.
즉 http 메시지 컨버터는 http 요청/응답 모두 사용한다.
canRead() , canWrite() : 메시지 컨버터가 해당 클래스, 미디어타입을 지원하는지 체크하는 기능이다.
read() , write() : 메시지 컨버터를 통해서 메시지를 읽고 쓰는 기능(canRead() , canWrite() 통과 후 적용)
몇 가지 주요한 http 메시지 컨버터는 다음과 같다.
ByteArrayHttpMessageConverter : byte[] 데이터를 처리한다.
클래스 타입: byte[] , 미디어타입: /(전부 가능) ,
요청 예) @RequestBody byte[] data
응답 예) @ResponseBody return byte[] 쓰기 미디어타입 application/octet-stream
StringHttpMessageConverter : String 문자로 데이터를 처리한다. 클래스 타입: String , 미디어타입: /
요청 예) @RequestBody String data
응답 예) @ResponseBody return "ok" 쓰기 미디어타입 text/plain
MappingJackson2HttpMessageConverter : application/json 클래스 타입: 객체 또는 HashMap , 미디어타입 application/json 관련
요청 예) @RequestBody HelloData data
응답 예) @ResponseBody return helloData 쓰기 미디어타입 application/json 관련
메시지 컨버터 동작 순서
1-HTTP 요청 데이터 읽기
1.1- HTTP 요청이 오고, 컨트롤러에서 @RequestBody , HttpEntity 파라미터를 사용한다.
1.2- 메시지 컨버터가 메시지를 읽을 수 있는지 확인하기 위해 canRead() 를 호출한다.
1.3- 대상 클래스 타입을 지원하는가.
예) @RequestBody 의 대상 클래스 ( byte[] , String , HelloData )
1.4- HTTP 요청의 Content-Type 미디어 타입을 지원하는가. 예) text/plain , application/json , /
1.5- canRead() 조건을 만족하면 read() 를 호출해서 객체 생성하고, 반환한다.
2- HTTP 응답 데이터 생성
2-1 컨트롤러에서 @ResponseBody , HttpEntity 로 값이 반환된다.
2-2 메시지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite() 를 호출한다.
2-3대상 클래스 타입을 지원하는가.
예) return의 대상 클래스 ( byte[] , String , HelloData )
2-4 HTTP 요청의 Accept 미디어 타입을 지원하는가.(더 정확히는 @RequestMapping 의 produces ) 예) text/plain , application/json , /
2-5 canWrite() 조건을 만족하면 write() 를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성한다.
4) 요청 매핑 핸들러 어댑터 구조