content-body를 통해 단순 텍스트를 얻는 방법에는 여러가지가 있다 .
request.getInputStream
이용@PostMapping("/request-body-string-v1")
public void requestBodyString(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletInputStream inputStream = request.getInputStream();
//stream은 bytecode이니 string으로 바꿀때는 어떤 인코딩으로 바꿀건지 설정해주어야 한다. 지정 안할경우 default값이 설정된다.
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("message-body={}", messageBody);
response.getWriter().write("ok");
}
위의 방식이 너무 지저분하다면 inputstream만 미리 떼와서 쓸수도 있다.
@PostMapping("/request-body-string-v2")//input stream과 writer를 그냥 받아서 바로 쓴다.
public void requestBodyStringV2(InputStream inputStream, Writer responseWriter)
throws IOException {
String messageBody = StreamUtils.copyToString(inputStream,
StandardCharsets.UTF_8);
log.info("messageBody={}", messageBody);
responseWriter.write("ok");
}
HttpEntity
이용 @PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
String messageBody = httpEntity.getBody();
log.info("messageBody={}", messageBody);
return new HttpEntity<>("ok");
}
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED)
TIP:
스프링MVC 내부적으로 HTTP메시지 바디를 읽어서 문자나 객체로 변환해서 전달하는데 이때 스프링은 HTTP 메시지 컨버터라는 기능을 사용하는 것이다.
@RequestBody
@RequestBody
를 사용하면 HTTP 메시지 바디 정보를 편리하게 조회할 수 있다. 참고로 헤더 정보가 필요하다면 HttpEntity
를 사용하거나 @RequestHeader
를 사용하면 된다. 이렇게 메시지 바디를 직접 조회하는 기능은 요청 파라미터를 조회하는 @RequestParam
, @ModelAttribute
와는 전혀 관계가 없다. @ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
log.info("messageBody={}", messageBody);
return "ok";
}
기본형은 아래와 같다.
1. HttpServletRequest를 사용해서 직접 HTTP 메시지 바디에서 데이터를 읽어와서, 문자로 변환한다.
2. 문자로 된 JSON 데이터를 Jackson 라이브러리인 objectMapper 를 사용해서 자바 객체로 변환한다.
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 helloData = objectMapper.readValue(messageBody, HelloData.class);
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
response.getWriter().write("ok");
}
@RequestBody
@RequestBody
를 지원하는데 바디의 타입이 JSON
일 경우 HTTP 메시지 컨버터가 자동으로 ObjectMapper를 호출해서 매개변수로 둔 객체에 맴버변수가 이름이 같은경우에 한해서 넣어 준다. @ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV2(@RequestBody HelloData helloData) throws IOException {
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
주의!
1.@RequestBody
는 생략 불가능!
@RequestBody
를 생략하면@ModelAttribute
가 적용되어버린다.
2. HTTP 요청시에 content-type이 application/json인지 꼭! 확인해야 한다.
그래야 JSON을 처리할 수있는 HTTP 메시지 컨버터가 실행된다.
HttpEntity<>
HttpEntity<String>
을 썼듯이 이번에는 HttpEntity<HelloData>
라고 쓰면된다. @ResponseBody
@PostMapping("/request-body-json-v4")
public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) throws IOException {
HelloData helloData = httpEntity.getBody();// <>제네릭 선언이 되어있어서 getBody를 하면 HelloData타입으로 받아짐
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
Tip.
단순히 받을때만@RequestBody
를 통해JSON
타입을 받는것이 아니라@ResponseBody
를 통해서 응답을 JSON으로 반환 할 수 있다. (당연히 HTTP 메시지 컨버터가 해준다.)