공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.
HTTP 요청 메시지 - 단순 텍스트
HTTP 메시지 바디를 통한 데이터 전송
- HTTP message body에 데이터를 직접 담아 요청
- HTTP API에서 주로 사용 (JSON, XML, TEXT)
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH 메서드에서 활용
- 요청 파라미터(@RequestParam, @ModelAttribute)와 다르게 HTTP 메시지 바디를 통해 데이터가 직접 전달됨
InputStream을 활용한 직접 읽기 - requestBodyStringV1
@Slf4j
@Controller
public class RequestBodyStringController {
@PostMapping("/request-body-string-v1")
public void requestBodyString(HttpServletRequest request,
HttpServletResponse response) throws IOException {
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody={}", messageBody);
response.getWriter().write("ok");
}
}
- HttpServletRequest를 사용하여 HTTP 메시지 바디의 데이터를 읽음
- StreamUtils.copyToString()을 이용하여 UTF-8 문자열로 변환
InputStream, OutputStream을 활용한 처리 - requestBodyStringV2
/**
* InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회
* OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력
*/
@PostMapping("/request-body-string-v2")
public void requestBodyStringV2(InputStream inputStream, Writer responseWriter) throws IOException {
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody={}", messageBody);
responseWriter.write("ok");
}
- InputStream을 직접 사용하여 요청 메시지 바디 읽기
- Writer를 이용하여 응답 메시지 바디에 직접 결과 출력
HttpEntity 활용 - requestBodyStringV3
/**
* HttpEntity: HTTP header, body 정보를 편리하게 조회
* - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
* - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
*/
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
String messageBody = httpEntity.getBody();
log.info("messageBody={}", messageBody);
return new HttpEntity<>("ok");
}
- HttpEntity를 사용하여 HTTP 헤더 및 바디 정보 조회
- 요청 파라미터와 관계없이 메시지 바디를 직접 조회 가능
- 응답에도 HttpEntity를 사용할 수 있으며, 헤더 포함 가능
ResponseEntity, RequestEntity
- RequestEntity: HttpMethod, URL 정보를 추가로 포함하며 요청에서 사용
- ResponseEntity: HTTP 상태 코드 설정 가능, 응답에서 사용
- 예제:
return new ResponseEntity<>("Hello World", responseHeaders, HttpStatus.CREATED);
@RequestBody 활용 - requestBodyStringV4
/**
* @RequestBody
* - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
* - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
*/
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
log.info("messageBody={}", messageBody);
return "ok";
}
- @RequestBody를 사용하여 HTTP 메시지 바디를 편리하게 조회
- 요청 파라미터(@RequestParam, @ModelAttribute)와 관계없이 메시지 바디만 처리
- HTTP 헤더 정보가 필요할 경우 HttpEntity 또는 @RequestHeader를 사용
@ResponseBody
- @ResponseBody를 사용하면 응답 데이터를 HTTP 메시지 바디에 직접 전달
- View를 사용하지 않음
요청 파라미터 vs HTTP 메시지 바디
기능 | 요청 파라미터 | HTTP 메시지 바디 |
어노테이션 | @RequestParam, @ModelAttribute | @RequestBody |
데이터 전달 방식 | URL 쿼리 스트링, HTML Form | HTTP 메시지 바디 |
데이터 형식 | Key-Value | JSON, XML, TEXT |
참고: HttpMessageConverter
- 스프링 MVC 내부에서 HTTP 메시지 바디를 읽고 변환하는 역할 수행
- 문자 또는 객체로 변환하여 컨트롤러에 전달
- StringHttpMessageConverter 적용됨
HTTP 요청 메시지 - JSON
JSON 데이터 처리 개요
- HTTP API에서 주로 JSON 데이터를 사용하여 요청을 보냄
- @RequestBody를 활용하여 JSON 데이터를 자바 객체로 변환 가능
- Jackson 라이브러리(ObjectMapper)를 사용하여 JSON을 객체로 변환
HttpServletRequest를 활용한 JSON 처리 - requestBodyJsonV1
@Slf4j
@Controller
public class RequestBodyJsonController {
private ObjectMapper objectMapper = new ObjectMapper();
@PostMapping("/request-body-json-v1")
public void requestBodyJsonV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody={}", messageBody);
HelloData data = objectMapper.readValue(messageBody, HelloData.class);
log.info("username={}, age={}", data.getUsername(), data.getAge());
response.getWriter().write("ok");
}
}
- HttpServletRequest를 사용하여 HTTP 메시지 바디에서 데이터 직접 읽기
- ObjectMapper를 활용하여 JSON 데이터를 자바 객체로 변환
@RequestBody를 활용한 JSON 처리 - requestBodyJsonV2
@ResponseBody
@PostMapping("/request-body-json-v2")
public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException {
HelloData data = objectMapper.readValue(messageBody, HelloData.class);
log.info("username={}, age={}", data.getUsername(), data.getAge());
return "ok";
}
- @RequestBody를 활용하여 요청 메시지 바디를 문자열로 변환 후 처리
- ObjectMapper를 사용하여 JSON 데이터를 객체로 변환
@RequestBody를 활용한 객체 변환 - requestBodyJsonV3
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData data) {
log.info("username={}, age={}", data.getUsername(), data.getAge());
return "ok";
}
- @RequestBody를 사용하여 JSON 데이터를 객체로 바로 변환
- HTTP 메시지 컨버터(MappingJackson2HttpMessageConverter)가 자동으로 처리
@RequestBody 생략 불가능한 이유
- @ModelAttribute와 @RequestParam이 생략되면 기본적으로 적용되는 규칙:
- String, int, Integer 같은 단순 타입 → @RequestParam 적용
- 나머지 객체 → @ModelAttribute 적용
- @RequestBody를 생략하면 @ModelAttribute가 적용되어 요청 파라미터로 처리됨
HttpEntity를 활용한 JSON 처리 - requestBodyJsonV4
@ResponseBody
@PostMapping("/request-body-json-v4")
public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) {
HelloData data = httpEntity.getBody();
log.info("username={}, age={}", data.getUsername(), data.getAge());
return "ok";
}
- HttpEntity를 활용하여 요청 본문을 직접 조회하고 JSON 데이터를 객체로 변환
- HTTP 메시지 컨버터를 통해 자동 변환
JSON 데이터 응답 처리 - requestBodyJsonV5
@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
log.info("username={}, age={}", data.getUsername(), data.getAge());
return data;
}
- @ResponseBody를 사용하여 JSON 데이터를 직접 응답으로 반환
- HTTP 메시지 컨버터를 활용하여 객체를 JSON으로 변환 후 응답
요청과 응답의 JSON 변환 과정
요청 | 응답 |
@RequestBody 사용 | @ResponseBody 사용 |
JSON → 객체 변환 | 객체 → JSON 변환 |
HttpMessageConverter 자동 적용 | HttpMessageConverter 자동 적용 |
주의 사항
- 요청 시 Content-Type: application/json을 반드시 설정해야 HTTP 메시지 컨버터가 JSON을 올바르게 처리함
- @RequestBody는 생략 불가능 (생략 시 @ModelAttribute가 적용됨)
- Jackson 라이브러리를 활용하여 JSON 데이터를 변환 (Spring Boot 기본 내장)
HTTP 응답 - 정적 리소스, 뷰 템플릿
스프링에서 응답 데이터를 만드는 방법
- 정적 리소스: HTML, CSS, JS 같은 정적인 리소스를 제공할 때 사용
- 뷰 템플릿: 동적인 HTML을 생성할 때 사용
- HTTP 메시지: API 응답(JSON 등)을 보낼 때 사용
정적 리소스 제공
- 스프링 부트는 /static, /public, /resources, /META-INF/resources 디렉토리에 있는 정적 리소스를 자동 제공
- 기본 정적 리소스 경로: src/main/resources/static
- 예제:
- src/main/resources/static/basic/hello-form.html
- http://localhost:8080/basic/hello-form.html로 접근 가능
뷰 템플릿을 사용한 응답 처리
- 동적인 HTML을 생성하여 응답
- 기본 뷰 템플릿 경로: src/main/resources/templates
뷰 템플릿 생성
src/main/resources/templates/response/hello.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p th:text="${data}">empty</p>
</body>
</html>
뷰 템플릿을 호출하는 컨트롤러
@Controller
public class ResponseViewController {
@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";
}
@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
model.addAttribute("data", "hello!!");
}
}
컨트롤러에서 뷰 반환 방식
- String을 반환하는 경우: @ResponseBody가 없으면 뷰 리졸버를 통해 템플릿이 렌더링 됨
- void를 반환하는 경우: 요청 URL을 기반으로 뷰 이름이 결정됨 (/response/hello → templates/response/hello.html 실행)
- 명시성이 부족하여 권장하지 않음
HTTP 메시지를 직접 응답하는 경우
- @ResponseBody 또는 HttpEntity를 사용하면 뷰 템플릿 없이 HTTP 메시지 바디에 직접 데이터 출력 가능
Thymeleaf 설정
- build.gradle에 다음 라이브러리 포함 (Spring Boot 기본 포함됨)
- implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
- 기본 설정 (변경 필요시 설정 가능)
- spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html
참고
- 스프링 부트의 타임리프 설정 관련 공식 문서: Spring Boot Reference
'Spring MVC' 카테고리의 다른 글
[MVC] 스프링 MVC - 기본 기능(3) (0) | 2025.03.02 |
---|---|
[MVC] 스프링 MVC - 기본 기능(2) (1) | 2025.02.24 |
[MVC] 스프링 MVC - 기본 기능(1) (0) | 2025.02.23 |
[MVC] 스프링 MVC - 구조 이해(3) (1) | 2025.02.22 |
[MVC] 스프링 MVC - 구조 이해(2) (0) | 2025.02.20 |