클라이언트-서버 구조에서 클라이언트가 전송한 데이터는 응용 계층부터 물리 계층을 타고 전송된다. 이때, 물리 계층까지 간 데이터는 바이너리 데이터 형태이므로, 서버 측(IntelliJ와 같은 프레임워크)은바이너리를 읽을 수 있는 InputStream과 같은 객체가 필요하다. 반대로서버에서 데이터를 적어서 클라이언트로 내려줄 때는 OutputStream을 사용할 수 있다.
InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회 OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력
🔎 HttpEntity
HttpEntity를 통해 HTTP header, body 정보를 편리하게 조회할 수 있다.
HttpEntity를 통해 HTTP body 읽기
응답에도 사용 가능하며 헤더 정보도 포함할 수 있다. 응답에 사용할 경우, 뷰를 조회하지 않고 데이터 그대로 클라이언트로 내려간다.
참고로, 요청 파라미터를 조회하는 기능과 관계없다.
💡 Stream 없이 바로 변환이 가능한 이유
Spring MVC 내부에서 HTTP 메시지 바디를 읽어서 문자나 객체로 변환해서 전달해 주기 때문이다. 이때 HTTP 메시지 컨버터(HttpMessageConverter)라는 기능을 사용한다.
💡 RequestEntity, ResponseEntity
RequestEntity : HttpMethod, url 정보를 추가할 수 있으며, 요청에서 사용한다. ResponseEntity : HTTP 상태 코드를 설정할 수 있고, 응답에서 사용한다.
🔎 @RequestBody
HTTP 메시지 바디 정보를 편리하게 조회할 수 있다.
뷰 리졸버를 통해 뷰를 조회하지 않으며, HttpMessageConverter가 동작하여 요청 바디의 내용을 그대로 가져온다.
바디를 조회하는 기능은 요청 파라미터를 조회하는 @RequestParam, @ModelAttribute와 관계없다.
@RequestBody를 통해 HTTP body 읽기
HttpEntity, @RequestBody, @ResponseBody는 HTTP 메시지 컨버터가 동작한다.
📌 HTTP API - JSON 처리
🔎 서블릿
HttpServletRequest를 사용해서 직접 HTTP body에서 데이터를 읽어올 수 있다.
이때, 요청 데이터가 JSON이므로 객체에 파싱 하길 원한다면 ObjectMapper를 사용해야 한다.
서블릿을 통해 HTTP body 읽기
🔎 @RequestBody
@RequestBody는 서블릿 사용 없이 단순 텍스트뿐만 아니라 JSON 데이터도 처리할 수 있다.
마찬가지로 JSON 데이터이지만 HTTP 메시지 컨버터는 HTTP body의 JSON 데이터도 문자나 객체로 변환해 준다.
따라서, ObjectMapper 사용 없이 body를 읽어 와서 HelloData라는 객체에 파싱 할 수 있다.
주의할 점은 @RequestBody를 생략할 수 없다는 것이다. 왜냐하면 HelloData는 클래스 타입이므로 생략할 경우, @ModelAttribute가 붙을 수 있기 때문이다.
@RequestBody를 통해 HTTP body 읽기
@ResponseBody가 붙었으므로 ViewResolver가 동작하지 않고 HTTP 메시지 컨버터가 동작하여 클라이언트로 내려줄 데이터를 HTTP body에 직접 지정할 수 있다. 리턴 값으로 이 데이터가 결정되는데, 아래처럼 HelloData의 data라는 객체를 그대로 내리면 해당 정보가 JSON으로 보인다.
요청/응답(Postman)
🔎 HttpEntity
단순 텍스트를 읽었을 때처럼 JSON도 HttpEntity를 통해 HTTP body를 읽을 수 있다.