ContentCachingRequestWrapper 사용 방법


사진: UnsplashJørgen Håland


Servlet에서 사용된 request와 response 복원 방법

  • Servlet에서 사용한 HttpServletRequest와 HttpServletResponse의 content는 다시 꺼내서 사용할 수 없다. 
  • Servlet 호출을 수행한 후에 AOP에서 request와 response의 content를 다시 확인하고 싶으면 어떻게 해야 할까?
  • 스프링 프레임워크에서 제공하는 ContentCachingRequestWrapper와 ContentCachingResponseWrapper를 이용하여 Servlet Filter를 추가하면 가능하다. 필터를 적용하면 request와 response의 content는 서블릿에서 사용된 후에, byte 배열로 복원할 수 있다. 


ServletFilter 클래스 생성

1
2
3
4
5
6
7
8
9
10
11
@Component
public class ContentCachingWrapperFilter extends OncePerRequestFilter {
 
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ContentCachingRequestWrapper wrappingRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappingResponse = new ContentCachingResponseWrapper(response);
        filterChain.doFilter(wrappingRequest, wrappingResponse);
        wrappingResponse.copyBodyToResponse();
    }
}
cs



web.xml에 filter 정의

1
2
3
4
5
6
7
8
<filter>
    <filter-name>contentCachingWrapperFilter</filter-name>
    <filter-class>com.xxx.pluto.web.filter.ContentCachingWrapperFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>contentCachingWrapperFilter</filter-name>
    <url-pattern>/api/v1/pluto/*</url-pattern>
</filter-mapping>
cs



AOP에서 Request, Response 복원

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void afterReturn(JoinPoint joinPoint, Object returnValue) throws Throwable {
    try {
 
        if (joinPoint.getArgs()[0instanceof ContentCachingRequestWrapper) {
            ContentCachingRequestWrapper ccrw = (ContentCachingRequestWrapper) joinPoint.getArgs()[0];
            String requestBody = new String(ccrw.getContentAsByteArray());
            System.out.println("request body is [" + requestBody + "]");
        }
 
        if (joinPoint.getArgs()[1instanceof ContentCachingResponseWrapper) {
            ContentCachingResponseWrapper ccrw = (ContentCachingResponseWrapper) joinPoint.getArgs()[1];
            String responseBody = new String(ccrw.getContentAsByteArray());
            System.out.println("Response Body is [" + responseBody + "]");
        }
 
    } catch(Exception e) {
        e.printStackTrace();
    }
}
cs



참고

org.springframework.web.util.ContentCachingRequestWrapper

HttpServletRequest wrapper that caches all content read from the input stream and reader, and allows this content to be retrieved via a byte array.

This class acts as an interceptor that only caches content as it is being read but otherwise does not cause content to be read. That means if the request content is not consumed, then the content is not cached, and cannot be retrieved via getContentAsByteArray().


org.springframework.web.util.ContentCachingResponseWrapper

HttpServletResponse wrapper that caches all content written to the output stream and writer, and allows this content to be retrieved via a byte array.



댓글 쓰기

0 댓글