[스프링 MVC - 백엔드 웹 개발 기술] 15. HTTP 응답 - 정적 리소스와 뷰 템플릿 반환 및 응답 방법
by ymkim01. 응답 - 정적 리소스, 뷰 템플릿
- 응답 데이터는 이미 앞에서 일부 다른 내용이지만, 응답 부분에 초점을 맞추어 정리해보자
- 스프링(서버)에서 응답 데이터를 만드는 방법은 크게 3가지 이다
01-1. 응답 데이터 생성 방법 3가지
- 정적 리소스
- 예) 웹 브라우저에 정적 HTML, css, js를 제공할 때 정적 리소스 사용
- Image, css, js
- 뷰 템플릿 사용
- 예) 웹 브라우저에 동적인 HTML을 제공할 때 뷰 템플릿 사용
- JSP, Thymleaf
- HTTP 메시지 사용
- HTTP API 제공 시 HTML이 아니라 데이터를 전달해야 하기에 Body에 JSON 담아서 전달
01-2. 스프링 부트는 정적 리소스 제공(src/main/resources)
정적 리소스란 해당 파일을 변경 없이 그대로 서비스 해주는 것을 의미한다
- 스프링부트는 webapps 와 같은 경로를 제공하지 않음
- 스프링부트는 클래스패스의 다음 디렉토리에 있는 정적 리소스를 제공한다
- src/main/resorces/static
- src/main/resorces/public
- src/main/resorces
- /META-INF/resources
- src/main/resources
- 리소스를 보관하는 곳
- 클래스패스의 시작 경로
- 해당 경로에 리소스를 넣어두면 스프링 부트가 정적 리소스로 서비스를 제공한다
- 정적 리소스 경로
- src/main/resources/static
- 다음 경로에 파일이 있으면
- src/main/resources/static/basic/hello-form.html
- 웹 접근 방식
- localhost:8080/bastic/hello-form.html 와 같이 접근이 가능
01-3.뷰 템플릿
- 뷰 템플릿을 거쳐 HTML이 생성되고, 뷰가 응답을 만들어서 전달한다
- 일반적으로 HTML을 동적으로 생성하는 용도로 사용하지만, 다른것들도 가능하다
- 즉, 뷰 템플릿이 만들 수 있는 것이라면 뭐든지 가능하다
- 스프링 부트는 기본 뷰 템플릿 경로를 제공한다
- 뷰 템플릿 경로
- src/main/resources/templates
- 뷰 템플릿 생성
- src/main/resources/templates/response/hello.html
01-4. ResponseViewController
package hello.springmvc.response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Controller
public class ResponseViewController {
/**
* model and view 사용
*/
@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
log.info("response-view-v1");
ModelAndView mav = new ModelAndView("response/hello")
.addObject("data", "hello!");
return mav;
}
/**
* model 사용
*/
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
log.info("response-view-v2");
model.addAttribute("data", "hello!");
return "response/hello";
}
/**
* 관례적으로 생략 -> 권장하지 않음
*/
@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
model.addAttribute("data", "hello!");
}
}
String을 반환하는 경우 - View or HTTP 메시지
- @ResponseBody가 없으면 response/hello 로 뷰 리졸버가 실행되어 뷰를 찾고 랜더링 한다
- @ResponseBody가 있으면 뷰 리졸버를 실행하지 않고, HTTP 메시지 바디에 직접 response/hello 라는 문자가 입력되어 반환된다
Void를 반환하는 경우
- @Controller를 사용하고 HttpServletResponse, OutputSteam(Writer) 같은 HTTP 메시지 바디를 처리하는 파라미터가 없으면 요청 URL을 참고해서 논리 뷰 이름으로 사용
- 요청 URL : /response/hello
- 실행 : templates/response/hello.html
- 참고로 위 방식은 명시성이 떨어져 권장하는 방식이 아님(사용하지 말자)
HTTP 메시지
- @ResponseEntity, HttpEntity 를 사용하면 뷰 템플릿이 아니라 HTTP 메시지 바디에 직접 응답 데이터 출력
01-5. hello.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p th:text="${data}">empty</p>
</body>
</html>
01-6. Thymleaf 라이브러리 설정 방법
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
- thymeleaf 사용을 위해 build.gradle에 위 라이브러리 추가(현재 추가되어 있음)
- 위 라이브러리가 존재하면 스프링부트가 ThymleafViewResolver와 필요한 스프링 빈들을 등록한다
- 또한 아래 설정도 사용한다, 이 설정은 기본 값이기에 변경이 필요한 경우만 설정하면 됨
# application.properties
spring.thymleaf.prefix=classpath:/templates/
spring.thymleaf.suffix=.html
01-7. HTTP 응답 - HTTP API, 메시지 바디에 직접 입력
- HTTP API를 제공하는 경우 HTML이 아니라 데이터를 전달해야 한다
- HTTP 메시지 바디에 JSON을 담아서 Client 측에 응답 한다
📂 참고 HTML이나 뷰 템플릿을 사용해도 결국 HTTP 응답 메시지 바디에 HTML 데이터가 담겨서 전달된다. 여기서 말하는 내용은 정적 리소스나 뷰 템플릿을 거치지 않고, 직접 HTTP 응답 메시지를 전달하는 경우를 말한다. @ResponseBody
01-8. ResponseBodyController
package hello.springmvc.response;
...
@Slf4j
//@ResponseBody
//@Controller
@RestController
public class ResponseBodyController {
// 서블릿 사용을 통해 HTTP API 응답
@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException {
response.getWriter().write("ok");
}
// ResponseEntity 사용
@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
return new ResponseEntity<>("ok", HttpStatus.OK);
}
// @ResponseBody 사용
// @ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "ok";
}
// ResponseEntity JSON 같이 사용
@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);
}
// @ResponseBody JSON 같이 사용
@ResponseStatus(HttpStatus.OK)
// @ResponseBody
@GetMapping("/response-body-json-v1")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
}
responseBodyV1
- 서블릿을 직접 다룰 때처럼 처리
- HttpServletResponse 객체를 통해 HTTP 메시지 바디에 직접 “ok” 전달
- response.getWriter().write(”ok”);
responseBodyV2
- ResponseEntity는 HttpEntity를 상속 받았는데 HttpEntity는 HTTP 메시지 헤더, 바디 정보를 가지고 있음
- ResponseEntity는 여기에 더하여 HTTP 응답 코드 설정까지도 가능함
responseBodyV3
@ResponseBody를 사용하면 view를 사용하지 않음
- HTTP 메시지 컨버터를 통해 HTTP 메시지 직접 입력 가능
- ResponseEntity 도 동일하게 동작 한다
responseBodyJsonV1
- ResponseEntity를 반환한다
- HTTP 메시지 컨버터를 통해 JSON 형식으로 변환되어 값을 응답
responseBodyJsonV2
- ResponseEntity는 HTTP 응답 코드 설정이 가능하다
- 하지만 @ResponseBody를 사용하면 응답 코드 설정이 까다로움
- 이 때 사용하는 것이 @ResponseStatus(HttpStatus.OK) 옵션이다
- 어노테이션이기 때문에 동적으로 변경은 불가능
- 동적 변경은 ResponseEntity를 사용해야 한다
@RestController
- @Controller + @ResponseBody 를 합친 어노테이션
- 주로 REST API 설계시 사용되는 어노테이션
'Spring MVC > 스프링 MVC - 백엔드 웹 개발 기술' 카테고리의 다른 글
블로그의 정보
기록하고, 복기하고
ymkim