응답 - 정적 리소스, 뷰 템플릿
정적 리소스
정적 리소스는 해당 파일 변경없이 그대로 서비스 하는것으로써
웹 브라우저에서는 정적인 HTML, css, js을 제공할 때 정적 리소스를 사용한다.
- 스프링 부트는 클래스패스의 다음 디렉토리에 있는 정적 리소스를 제공한다.
- /static , /public , /resources , /META-INF/resources
src/main/resources는 리소스를 보관하는 곳이고, 또 클래스패스의 시작 경로이다.- 따라서 다음 디렉토리에 리소스를 넣어두면 스프링 부트가 정적 리소스로 서비스를 제공한다.
- 정적 리소스 경로:
src/main/resources/static - ex)
src/main/resources/static/basic/hello-form.html에 있는 파일을 접근할땐
웹 브라우저에서 다음과 같이 실행하면 된다.http://localhost:8080/basic/hello-form.html뷰 템플릿
- 정적 리소스 경로:
뷰 템플릿을 거쳐서 HTML이 생성되고, 뷰가 응답을 만들어서 전달한다.
일반적으로 HTML을 동적으로 생성하는 용도로 사용하지만, 다른 것들도 가능하다. 뷰 템플릿이 만들 수 있는 것이라면 뭐든지 가능하다.
-
-
- 뷰 템플릿 기본 경로
src/main/resources/templates
- 뷰 템플릿을 호출하는 2가지 방법보통 2번째 것을 자주 쓴다. 1번째 것은 너무 손이 많이가서..
@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"; }
HTTP 응답 - HTTP API, 메시지 바디에 직접입력
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"; }
JSON 타입을 보낼 때
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을 보내고 싶다면사용이 편리하고 첫 번째 방법과 결과는 동일하지만 HTTP status가 애노테이션에 고정된다는 점이 단점이다. @ResponseStatus(HttpStatus.OK) @ResponseBody @GetMapping("/response-body-json-v2") public HelloData responseBodyJsonV2() { HelloData helloData = new HelloData(); helloData.setUsername("userA"); helloData.setAge(20); return helloData; }
TIP!
만약@ResponseBody를 함수마다 붙이기엔 너무 많고 함수가 속해있는 함수 전부 HTTP 메시지 바디에 직접 응답하고 싶다면@RestController를 클래스 단에 붙여주면 된다.
HTTP 메시지 컨버터
HTTP 메시지 컨버터가 적용되는 경우
@ResponseBodyorHttpEntity(ResponseEntity)사용시 -> HTTP 응답- HTTP의 Body에 문자 대신 내용을 직접 반환
viewResolver대신에HttpMessageConverter가 동작- 기본 문자처리는
StringHttpMessageConverter가 작동하고 - 기본 객체처리는
MappingJackson2HttpMessageConverter가 동작한다. - byte 처리 등등 기타 여러 Http 메시지 컨버터가 기본으로 등록되있음
@RequestBodyorHttpEntity(RequestEntity)사용시 -> HTTP 요청- 위와 거의 동일(역순일 뿐)
HTTP 메시지 컨버터 우선순위
당연히 여러종류의 HTTP메시지 컨버터가 있으니 어떤걸 먼저 쓸지 우선 순위가 있다.
우선순위는 다음과 같다.(이게 전부는 아님)
0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
위의 컨버터가 대표적인 HTTP메시지 컨버터다.
ByteArrayHttpMessageConverter:byte[]데이터를 처리한다.- 클래스 타입:
byte[], 미디어타입:*/*
요청 예)@RequestBody byte[] data
응답 예)@ResponseBody return byte[]쓰기 미디어타입application/octet-stream
- 클래스 타입:
StringHttpMessageConverter:String문자로 데이터를 처리한다.- 클래스 타입: String , 미디어타입:
*/*
요청 예)@RequestBody String data
응답 예)@ResponseBody return "ok"쓰기 미디어타입text/plain
- 클래스 타입: String , 미디어타입:
MappingJackson2HttpMessageConverter:application/json- 클래스 타입: 객체 또는
HashMap, 미디어타입application/json관련
요청 예)@RequestBody HelloData data
응답 예)@ResponseBody return helloData쓰기 미디어타입application/json관련
- 클래스 타입: 객체 또는
HTTP 요청 데이터 읽기
- HTTP 요청이 오고, 컨트롤러에서 @RequestBody , HttpEntity 파라미터를 사용한다.
- 메시지 컨버터가 메시지를 읽을 수 있는지 확인하기 위해 canRead() 를 호출한다.
- 대상 클래스 타입을 지원하는지 체크
예) @RequestBody 의 대상 클래스 ( byte[] , String , HelloData ) - HTTP 요청의 Content-Type 미디어 타입을 지원하는가.
예) text/plain , application/json ,*/* - canRead() 조건을 만족하면 read() 를 호출해서 객체 생성하고, 반환한다.
HTTP 응답 데이터 생성
- 컨트롤러에서 @ResponseBody , HttpEntity 로 값이 반환된다.
- 메시지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite() 를 호출한다.
- 대상 클래스 타입을 지원하는지 체크
예) return의 대상 클래스 ( byte[] , String , HelloData ) - HTTP 요청의 Accept 미디어 타입을 지원하는가.(더 정확히는 @RequestMapping 의 produces )
예) text/plain , application/json ,*/* - canWrite() 조건을 만족하면 write() 를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성한다.
요약: HTTP 메시지 컨버터가 canWrite나 canRead를 통해 자동으로 해석하여 걸맞는 값을 읽기or 생성을 해준다고 생각하자
'웹개발 > 웹서버' 카테고리의 다른 글
| 스프링 MVC: 요청 메시지 (0) | 2024.01.19 |
|---|---|
| 스프링 MVC: RequestMapping & RequestParameter (0) | 2024.01.14 |
| 스프링 MVC: 로깅 간단 설명 (1) | 2024.01.10 |
| 스프링 MVC: HttpServletRequest의 간단한 사용법 예시 (0) | 2024.01.07 |
| HTTP 헤더에 대해 조금 더 알아보자...(캐시와 조건부 요청) (0) | 2023.12.26 |