본 포스팅은 context7 mcp 서버를 활용하여 개념을 정리하였습니다.
클라이언트에서 서버로 요청 데이터를 전달할 때는 다음과 같은 3가지 방법이 있다.
/url?username=mindfulness&age=20
메세지 바디가 없이 URL의 쿼리파라미터에 데이터를 포함해 전달한다.
GET /path?username=kim&age=20 HTTP/1.1
Header...
(Body 없음)
POST /submit HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2( MindfulnessData mindfulnessData) {
log.info("username = {}, age = {}", mindfulnessData.getUsername(), mindfulnessData.getAge());
log.info("mindfulness= {}",mindfulnessData);
return "ok";
}
POST /json HTTP/1.1
Content-Type: application/json
{"username": "kim", "age": 20}
@PostMapping("/request-body-spring-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) throws IOException {
String messageBody = httpEntity.getBody();
log.info("messageBody= {}", messageBody);
return new HttpEntity<>("ok");
}
HandelrMethodArgumentResoler가 파라미터가 HTTPEntity임을 인지HttpMessageConverter 목록에서 요청의 Content-Type에 맞는 변환기를 선택Converter가 String으로 변환HttpHeaders로 생성HTTPEntity(body,headers)에 담아서 컨트롤러에 주입HttpEntity<String> 도 다시 HttpMessageConverter가 body를 변환해서 응답에 작성한다. 그렇다면 다음과 같은 장점이 있다.
1. HTTP body 변환 자동화
TCP기반 HTTP의 동작원리상 스트림 처리를 개발자가 직접 HTTPServlet api를 사용하여 처리해야했지만, 이를 HTTPEntity가 처리한다.
2. HTTP header+ body를 하나의 객체로 관리
3. servlet api의존 제거
-> 테스트 가능성과 모듈성이 높아진다.
4. 요청, 응답 모두 다음과 같이 다룰수 있다.
return new ResponseEntity<>("ok", HTTPStatus.OK);
궁금증: 그렇다면 Servlet이란 무엇이고 Stream은 왜 사용할까?
웹 요청이 들어오면 WAS(Web Application Server: tomcat등)가 먼저 받는다. WAS는 요청정보를 자바 객체로 바꿔 개발자가 사용할 수 있게 해주는데, 이때 HttpServeltRequest가 만들어진다.
클라이언트가 보낸 HTTP 요청 정보를 담고 있는 객체
✅ HttpServletRequest
HTTP header
query parameter
cookie
body(InputStream)
remote address 등
✅ HttpServletResponse
서버에서 클라이언트로 보내는 HTTP 응답 정보를 담는 객체
HTTP status code
header
body
✅이유 1. HTTP body는 크기제한이 없으므로 메모리에 한번에 올리면 위험!!
파일업로드 2GB
JSON 100MB
이미지 업로드
이걸 모두 String으로 한방에 읽어 버리면 메모리 폭발!!
그래서 WAS는 body를 한번에 제공하지 않고:
1byte, 1byte, 1byte…
또는
버퍼 단위(1024byte, 4096byte…)
이렇게 "조각조각 흘러가는 데이터" 형태로 제공한다.
이게바로 InputStream
✅이유2. network는 "스트림 기반 프로토콜이다"
TCP => 데이터가 흘러 들오노는 형태(Streaming)
HTTP -> TCP위에서 동작하므로 body는 "흐름"으로 전송된다.
즉, 입력스트림은 네트워크 구조와 맞닿아 있음
✅이유3. 데이터의 종류를 미리 알 수 없음
HTTP body에는 다음과 같은 데이터가 올수 있는데,
plain text
JSON
XML
이미지
동영상
등등등...
공통점은 "bytes"라는 것 뿐 -> 그래서 InputStream을 사용한다 .
| 방식 | Body | Header | HttpEntity 필요성 | 설명 |
|---|---|---|---|---|
| GET Query | ❌ 없음 | 있음 | 낮음 | Body가 없으므로 HttpEntity 사용 이점 거의 없음 |
| POST Form | 있음 (urlencoded) | 있음 | 중간 | HttpEntity로 받을 수 있지만 스프링의 ModelAttribute가 더 편함 |
| POST raw body(JSON/text/XML) | ✔ JSON 등 raw body | ✔ Content-Type 중요 | 최고 | HttpMessageConverter가 자동 파싱 → HttpEntity가 가장 편리 |