티스토리 뷰
HTTP 요청 메시지 - JSON
이번에는 HTTP API에서 주로 사용하는 JSON 데이터 형식을 조회하기
V1 - 기존 서블릿에서 사용했던 방식
RequestBodyJsonController
@Slf4j
@Controller
public class RequestBodyJsonController {
// ObjectMapper 객체를 생성.
// ObjectMapper는 JSON 데이터를 자바 객체로 변환하거나 자바 객체를 JSON으로 직렬화하는 데 사용.
private ObjectMapper objectMapper = new ObjectMapper();
@PostMapping("/request-body-json-v1")
public void requestBodyJsonV1(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// HTTP 요청의 입력 스트림을 얻어온다.
// 이 입력 스트림은 요청 바디에 있는 데이터를 읽기 위해 사용.
ServletInputStream inputStream = request.getInputStream();
// 입력 스트림에서 데이터를 읽어와 문자열로 변환.
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
// 로그에 읽어온 메시지 바디를 출력.
log.info("messageBody={}", messageBody);
// ObjectMapper를 사용하여 JSON 문자열을 HelloData 클래스의 객체로 변환.
HelloData data = objectMapper.readValue(messageBody, HelloData.class);
// 변환된 객체에서 사용자 이름(username)과 나이(age)를 가져와 로그에 출력.
log.info("username={}, age={}", data.getUsername(), data.getAge());
// HTTP 응답에 "ok" 문자열을 쓰고 응답을 완료함.
response.getWriter().write("ok");
}
}
Postman 테스트
POST http://localhost:8080/request-body-json-v1
raw, JSON, content-type: application/json
{"username":"hello", "age":20}
실행하면
잘 출력 됨을 확인할 수 있음
requestBodyJsonV2 - @RequestBody 문자 변환
/**
* @RequestBody
* HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
*
* @ResponseBody
* - 모든 메서드에 @ResponseBody 적용
* - 메시지 바디 정보 직접 반환(view 조회X)
* - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
* @ResponseBody 어노테이션을 사용하여 이 메서드가 메시지 바디 정보를 직접 반환하고
* 뷰를 조회하지 않도록 설정. 이것은 일반적으로 RESTful API 엔드포인트에서 사용됨.
*/
@ResponseBody
@PostMapping("/request-body-json-v2")
public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException {
// JSON 형식의 메시지 바디를 문자열로 전달받아서,
// ObjectMapper를 사용하여 HelloData 객체로 변환.
HelloData data = objectMapper.readValue(messageBody, HelloData.class);
// 변환된 객체에서 사용자 이름과 나이를 가져와 로그에 출력.
log.info("username={}, age={}", data.getUsername(), data.getAge());
// "ok" 문자열을 반환. 이 문자열은 HTTP 응답의 바디에 들어간다.
return "ok";
}
고민
문자로 변환하고 다시 json으로 변환하는 과정이 불편하다. @ModelAttribute처럼 한번에 객체로
변환할 수는 없을까?
requestBodyJsonV3 - @RequestBody 객체 변환
/**
* @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
* HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter (contenttype: application/json)
*/
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData data) {
// @RequestBody 어노테이션을 사용하여 JSON 데이터를 자동으로 HelloData 객체로 변환하고,
// 이 객체를 메서드 매개변수로 직접 전달받는다.
// 변환된 객체에서 사용자 이름과 나이를 가져와 로그에 출력.
log.info("username={}, age={}", data.getUsername(), data.getAge());
// "ok" 문자열을 반환합니다. 이 문자열은 HTTP 응답의 바디에 들어간다.
return "ok";
}
@RequestBody 객체 파라미터
- @RequestBody HelloData data
- @RequestBody에 직접 만든 객체를 지정할 수 있다.
- HttpEntity, @RequestBody 를 사용하면 HTTP 메시지 컨버터가
HTTP 메시지 바디의 내용을 우리가 원하는 문자나 객체 등으로 변환해준다.
- HTTP 메시지 컨버터는 문자 뿐만 아니라 JSON도 객체로 변환해주는데,
우리가 방금 V2에서 했던 작업을 대신 처리해준다.
- 자세한 내용은 뒤에 HTTP 메시지 컨버터에서 다룬다.
@RequestBody는 생략 불가능
@ModelAttribute 에서 학습한 내용을 떠올려보자.
스프링은 @ModelAttribute , @RequestParam 과 같은 해당 애노테이션을 생략시 다음과 같은 규칙을 적용한다.
* String , int , Integer 같은 단순 타입 = @RequestParam
* 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 외)
따라서 이 경우 HelloData에 @RequestBody 를 생략하면 @ModelAttribute 가 적용되어버린다.
HelloData data => @ModelAttribute HelloData data
따라서 생략하면 HTTP 메시지 바디가 아니라 요청 파라미터를 처리하게 된다.
물론 앞서 배운 것과 같이 HttpEntity를 사용해도 된다.
requestBodyJsonV4 - HttpEntity
@ResponseBody
@PostMapping("/request-body-json-v4")
public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) {
// HttpEntity를 사용하여 요청 바디를 다룬다.
// HttpEntity는 HTTP 요청과 응답의 헤더와 바디를 쉽게 다루기 위한 클래스.
HelloData data = httpEntity.getBody();
log.info("username={}, age={}", data.getUsername(), data.getAge());
return "ok";
}
- HttpEntity는 HTTP 요청과 응답의 헤더 및 바디를 포함하는 객체이다.
- httpEntity.getBody()를 사용하여 요청 바디에서 JSON 데이터를 HelloData 객체로 가져온다.
이 객체에는 요청 바디의 내용이 자동으로 매핑된.
requestBodyJsonV5
/**
* @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
* HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter (contenttype: application/json)
*
* @ResponseBody 적용
* - 메시지 바디 정보 직접 반환(view 조회X)
* - HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter 적용 (Accept: application/json)
*/
@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
// @RequestBody 어노테이션을 사용하여 JSON 데이터를 자동으로 HelloData 객체로 변환하고,
// 이 객체를 메서드의 반환값으로 직접 반환합니다. 이 메서드는 HelloData 객체를 JSON으로 직렬화하여
//클라이언트에게 응답으로 전송.
// 변환된 객체에서 사용자 이름과 나이를 가져와 로그에 출력
log.info("username={}, age={}", data.getUsername(), data.getAge());
// HelloData 객체를 반환. 이 객체는 JSON으로 변환되어 HTTP 응답의 바디에 들어간다.
return data;
}
'[개발] - Spring > MVC 1' 카테고리의 다른 글
HTTP 응답 - HTTP API, 메시지 바디에 직접 입력 (0) | 2023.10.10 |
---|---|
HTTP 응답 - 정적 리소스, 뷰 템플릿 (1) | 2023.10.10 |
HTTP 요청 메시지 - 단순 텍스트 (0) | 2023.10.09 |
HTTP 요청 파라미터 - @ModelAttribute (0) | 2023.10.08 |
HTTP 요청 파라미터 - @RequestParam (0) | 2023.10.08 |