ServletResponse
서블릿에서 클라이언트에게 응답을 제공하기 위한 목적의 인터페이스이다.
HttpServletResponse
서블릿에서 Http 응답을 제공하기 위한 목적의 인터페이스이다.
HttpMessage
Spring에서 Http 요청 및 응답 메시지를 다루기 위한 목적의 기본 인터페이스이다.
HttpOutputMessage
말그대로 HTTP output message를 위한 인터페이스이다.
Http 서버 입장에서 보자.
- Http request는 input message이다. 따라서 server side에서 Http 요청을 다룰 때 사용하는 인터페이스는 HttpInputMessage 를 상속 받은 ServerHttpRequest 인터페이스이다.- Http response는 output message이다. 따라서 server side에서 Http 응답을 다룰 때 사용하는 인터페이스는 HttpOutputMessage 를 상속 받은 ServerHttpResponse 인터페이스이다.
Http 클라이언트 입장에서 보자.
- Http request는 output message이다. 따라서 client side에서 Http 요청을 다룰 때 사용하는 인터페이스는 HttpOutputMessage 를 상속 받은 ClientHttpRequest 인터페이스이다.- Http response는 input message이다. 따라서 client side에서 Http 응답을 다룰 때 사용하는 인터페이스는 HttpInputMessage 를 상속 받은 ClientHttpResponse 인터페이스이다.
해당 포스트에서는 server side에서의 HTTP 응답 상황을 다룬다. 따라서 ServerHttpResponse의 구현체인 ServletServerHttpResponse를 언급할 것이다.
차이점을 알아보자.
응답을 하기위해서는 OutputStream에 응답할 데이터를 써주어야 한다.
스프링에서 Http 응답을 하는 경우에도 마찬가지이다. 응답을 하기 위해서는 OutputStream에 값을 작성해야한다.
지금까지 스프링에서 API를 구현할 때, 컨트롤러에서 응답할 값(객체)을 반환하면 이것이 응답 데이터가 되었을 것이다.
반환된 객체는 문자열로 변환된 뒤에 바이트 코드가 된다. 이렇듯 반환한 응답 value가 Http 응답 메시지의 본문에 담겨 전송될 수 있도록 수행되는 값의 변환 작업(직렬화)은 HttpMessageConverter가 담당한다.
이때 직렬화된 데이터는 ServletServerHttpResponse 가 가지고 있는 OutputStream에 작성된다.
하지만 실제 컨버터가 사용하는 ServletServerHttpResponse 의 코드를 찾아보면, 메서드 내부에서 HttpServletResponse 의 메서드를 호출하는 것을 알 수 있다. 다음은 ServletServerHttpResponse class의 코드이다.
ServletServerHttpResponse는 마치 HttpServletResponse 의 Wrapper 클래스처럼, HttpServletResponse를 멤버변수로 두고 이를 기반으로 하는 메서드를 제공한다.
따라서 HttpMessageConverter는 ServletServerHttpResponse 를 매개로 HttpServletResponse를 사용하는 것이라는 사실을 깨달을 수 있다.
두 인터페이스의 차이점을 찾아본 사람은 알겠지만 공식문서에서 설명하는 두 인터페이스의 역할이 같다고 느낄 정도로 유사하다. 분명한 것은 단지 누가 제공하느냐의 차이일 뿐이다.
Http 응답에 사용할 수 있는 HttpServletResponse 인터페이스가 있는데 ServletServerHttpResponse 를 따로 정의한 이유가 무엇일까?
HttpServletResponse 은 서블릿에서 제공하는 인터페이스이다. 그러므로 스프링이 해당 인터페이스를 직접적으로 이용하기 보다는 Adapter 패턴을 적용하듯, ServletServerHttpResponse 의 멤버 변수로 HttpServletResponse 를 가지고 있는 방식을 사용함으로써 의존성을 낮추기 위한 의도로 추측된다.
추후 찾아보니, 이런 방식을 Decorator pattern이라고 부르며, 이펙티브 자바에서 '상속보다는 조합을 사용하라'라는 내용으로 설명하고 있었다.
reference
https://www.springcloud.io/post/2022-02/elegantly-read-and-write-httpbody/#gsc.tab=0
How to elegantly read and write HttpServletRequest and HttpServletResponse request bodies
Recently, many interactions have to deal with the native HttpServletRequest and HttpServletResponse. Read body data from HttpServletRequest and encapsulate it into some kind of data structure; write data to HttpServletResponse and respond. The traditional
www.springcloud.io
'Spring' 카테고리의 다른 글
외부 API 비동기 호출로 성능 개선하기 (0) | 2025.03.04 |
---|---|
@ResponseBody를 이용한 응답 과정 알아보기 (0) | 2024.09.13 |
서블릿에서 HTTP Response 보내기 (0) | 2024.08.31 |
영속성 관리(ORM 표준 기술 {3} ) (0) | 2023.07.06 |
JPA(자바 ORM 표준 JPA 프로그래밍-기본편) { 2 } (0) | 2023.07.05 |