1

I have a spring boot application. And now I need to read request and response in interceptor.I use a HttpServletRequestWrapper replace the request in DispatcherServlet

@Component("dispatcherServlet")
public class FofDisPatcherServlet extends DispatcherServlet {
    @Override
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        MultiReadHttpServletRequest requestWrapper = null;
        try {
            requestWrapper = new MultiReadHttpServletRequest(request);
            super.doDispatch(requestWrapper, response);
        } catch (Exception e) {
            super.doDispatch(request,response);
        }
    }
}

And in my interceptor , I can read the request body. But when I want to read the response body, it doesn't works.when I replace the response in the CustomerDispatcherServlet I got nothing response.I have tried ContentCachingResponseWrapper , but I got the payload with "".

It's a old question.and I have search some questions but didn't find a suitable solution.

I know I can solve the problem with AOP.But I want to know how can I do it in the interceptor?


here is my interceptor code

public class CustomerInterceptor extends HandlerInterceptorAdapter{
    @Override
    public void postHandle(...){
        MultiReadHttpServletRequest req = (MultiReadHttpServletRequest) request;
        ContentCachingResponseWrapper res = new ContentCachingResponseWrapper(response);
        Byte[] body = res. getContentAsByteArray();
        ...
    }
}

the body I got is [].

linghu
  • 133
  • 3
  • 16
  • Can you share more of your code? How did you use `ContentCachingResponseWrapper `? As javadoc says you should call `getContentAsByteArray()` method on it to retrieve content – Leffchik Aug 25 '17 at 10:44
  • Yes,I use `getContentAsByteArray()` but I get content with "". – linghu Aug 25 '17 at 10:51
  • Can you share the interceptor code, the problem is in the interceptor part. – Vivek Singh Aug 25 '17 at 10:52
  • You should wrap your response object in servlet filter, not in the interceptor. – Leffchik Aug 25 '17 at 10:57
  • @Leffchik But why it does not work in the interceptor.I didn't find it in the document. – linghu Aug 25 '17 at 11:04
  • You can look under the hood of `ContentCachingResponseWrapper`. As java doc says it caches all content written to the `getOutputStream()` output stream. But if you wont wrap you response in servlet filter - your controller response will be written into different response `getOutputStream()` object. – Leffchik Aug 25 '17 at 11:15

3 Answers3

1

Try this:

@Component("dispatcherServlet")
public class FofDisPatcherServlet extends DispatcherServlet {
    @Override
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        MultiReadHttpServletRequest requestWrapper = null;
        try {
            requestWrapper = new MultiReadHttpServletRequest(request);
            super.doDispatch(requestWrapper, new ContentCachingResponseWrapper(request));
        } catch (Exception e) {
            super.doDispatch(request,response);
        }
    }
}

.

public class CustomerInterceptor extends HandlerInterceptorAdapter{
    @Override
    public void postHandle(..., HttpServletResponse response){
        if (response instanceof ContentCachingResponseWrapper) {
            Byte[] body = ((ContentCachingResponseWrapper)response). getContentAsByteArray();
        }
        ...
    }
}
vinS
  • 1,417
  • 5
  • 24
  • 37
Leffchik
  • 1,950
  • 14
  • 16
1

After few days .I find the answer.In the CustomerDispatcherServlet I should add responseWrapper.copyBodyToResponse()

the CustomerDIspatcherServlet like this:

@Component("dispatcherServlet")
public class FofDisPatcherServlet extends DispatcherServlet {
    @Override
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        MultiReadHttpServletRequest requestWrapper = null;
        try {
            requestWrapper = new MultiReadHttpServletRequest(request);
            if (!(response instanceof ContentCachingResponseWrapper)) {
                ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
                super.doDispatch(requestWrapper, responseWrapper);
                responseWrapper.copyBodyToResponse();
            }else {
                super.doDispatch(requestWrapper, response);
            }
        } catch (Exception e) {
            super.doDispatch(request, response);
        }
    }
}    
linghu
  • 133
  • 3
  • 16
0

The error is in your code

public class CustomerInterceptor extends HandlerInterceptorAdapter{
    @Override
    public void postHandle((HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){
        MultiReadHttpServletRequest req = (MultiReadHttpServletRequest) request;
        ContentCachingResponseWrapper res = new ContentCachingResponseWrapper(response);
        Byte[] body = res. getContentAsByteArray();
        ...
    }
}

You are passing request in ContentCachingResponseWrapper.

See this question very similar problem .

Vivek Singh
  • 646
  • 3
  • 10
  • 25