문서를 보면 InputStream과 Writer를 직접 가져올 수 있어 코드가 간략해진다.
InputStream
HTTP 요청 메시지 바디의 내용을 직접 조회한다.
OutputStream
HTTP 응답 메시지 바디에 결과를 직접 출력한다.
HttpEntity
@Slf4j
@Controller
public class RequestBodyStringController {
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
// 스프링이 알아서 문자로 컨버팅 해준다.
String messageBody = httpEntity.getBody();
log.info("messageBody = {}", messageBody);
// HTTP 바디 정보를 직접 반환해준다.
return new HttpEntity<>("ok");
}
}
HttpEntity
HTTP header, body를 편리하게 조회할 수 있다.
요청 파라미터를 조회하는 기능과는 아무 관계가 없다.
@RequestParam, @ModelAttribute
이 둘은 요청 파라미터인 쿼리 파라미터나 HTML Form 방식이라는 걸 잊지 말자.
응답에도 사용 가능하다.
메시지 바디 정보를 직접 반환할 수 있다.
헤더 정보를 포함할 수 있다.
view 조회는 불가하다.
메시지 컨버터를 통해 HTTP 바디를 문자나 객체로 변환한다.
HttpEntity를 상속받은 객체들
RequestEntity
ResponseEntity
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED)
HTTP 상태 코드를 넣어줄 수 있다.
@RequestBody, ResponseBody
@Slf4j
@Controller
public class RequestBodyStringController {
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
log.info("messageBody = {}", messageBody);
return "ok";
}
}
@RequestBody
HttpEntity 대신 더 간단하게 사용할 수 있다.
헤더 정보가 필요하면 HttpEntity나 @RequestHeader를 사용하면 된다.
@ResponseBody
HTTP 메시지 바디에 응답을 직접 담아 전달할 수 있다.
물론 둘 다 view는 사용하지 않는다.
요청 파라미터 vs HTTP 메시지 바디
다시 한 번 강조하지만, 이렇게 메시지 바디를 조회하는 기능은 요청 파라미터를 조회하는 @RequestParam, @ModelAttribute와는 전혀 관계가 없다.
요청 파라미터 조회
@RequestParam
HTTP 메시지 바디 직접 조회
@RequestBody
JSON
HttpServletRequest
@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");
}
}
Jackson 라이브러리인 objectMapper로 JSON 데이터를 컨버팅한다.
@RequestBody
@Slf4j
@Controller
public class RequestBodyJsonController {
private ObjectMapper objectMapper = new ObjectMapper();
@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로 InputStream을 사용하는 번거로운 절차를 생략했다.
여전히 objectMapper로 굳이 바꿔줘야 한다.
@Slf4j
@Controller
public class RequestBodyJsonController {
private ObjectMapper objectMapper = new ObjectMapper();
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData data) {
log.info("username={}, age={}", data.getUsername(), data.getAge());
return "ok";
}
}
String 대신 객체 자체로 바로 받을 수 있다.
HTTP 메시지 컨버터가 HTTP 메시지 바디를 문자나 객체, JSON으로 바꿔준다.
@RequestBody는 생략할 수 없다.
생략 시 단순한 타입 외에는 모두 @ModelAttribute를 적용하도록 되어있기 때문이다.
따라서 메시지 바디가 아니라 요청 파라미터를 처리하게 된다.
ResponseBody
@Slf4j
@Controller
public class RequestBodyJsonController {
@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
log.info("username={}, age={}", data.getUsername(), data.getAge());
// 객체를 자동으로 JSON으로 반환해준다.
return data;
}
}
@RequestBody
JSON 요청 -> HTTP 메시지 컨버터 -> 객체
content-type:application/json
@ResponseBody
객체 -> HTTP 메시지 컨버터 -> JSON 응답
accept:application/json
참고로, content-type이 application/json이어야 JSON을 사용할 수 있는 메시지 컨버터가 실행된다.
HttpEntity
@Slf4j
@Controller
public class RequestBodyJsonController {
private ObjectMapper objectMapper = new ObjectMapper();
@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";
}
}