javaspringspring-bootspring-mvcnetflix-zuul

How to get request and response as string after RequestDispatcher forward


In my Springboot application, I use RequestDispatcher forward to send the request and response to a remote service. Now I need to get that response and request as string to log it into database. The request and response both contain JSON data.

RequestDispatcher requestDispatcher = request.getRequestDispatcher(configAPI.getUserByPhoneUrl());
requestDispatcher.forward(request, response);

The RequestDispatcher will modify the response in-place. So after the forward() function, I'm unable to get the json from the response created by requestDispatcher.forward(request, response).

@RequestMapping(value = "/getUserByPhone", method = {RequestMethod.GET}, produces = "application/json;charset=utf-8")
    public void getUserbyIsdn(HttpServletRequest request, HttpServletResponse response) {
            // Forward the request to the remote service
            RequestDispatcher requestDispatcher = request.getRequestDispatcher(configAPI.getUserByPhoneUrl());
            requestDispatcher.forward(request, response);
            // response now has result from remote service
            // TODO: print out json in response here
    }

Any idea on how to get response as json?

I've try using HttpServletResponseWrapper to access the response but unable to. Example code using HttpServletResponseWrapper:

HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request);
            HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);

            // Forward the request to the remote service
            request.getRequestDispatcher(configAPI.getUserByPhoneUrl()).forward(requestWrapper, responseWrapper);

but is result in NullPointerException because ApplicationContext request is not set.


Solution

  • After some trying out, I was able to get response and request json string using ContentCachingRequestWrapper and ContentCachingResponseWrapper. The controller now become like this:

    @RequestMapping(value = "/getUserByPhone", method = {RequestMethod.GET}, produces = "application/json;charset=utf-8")
        public void getUserbyIsdn(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
            ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
            requestWrapper.getRequestDispatcher(configAPI.getApi_getUserbyIsdn_user()).forward(requestWrapper, responseWrapper);
            // do what ever you want here with response and request
            apiLogService.addApiLog(requestWrapper, responseWrapper, "getUserByIsdn", timer);
    
            // have to has this to return original response of other service
            responseWrapper.copyBodyToResponse();
        }
    

    Function addApiLog:

    public void addApiLog(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) {
        String requestJson = IOUtils.toString(request.getContentAsByteArray());
        String responseJson = IOUtils.toString(response.getContentAsByteArray());
        // handle json String using JSONObject or GSON as needed
    }