lzkx1234
lzkx1234

Reputation: 51

How can we get and set response body in Spring Boot Filter?

I have a Spring MVC application which return ResponseEntity and clientResponse object as response body:

@RestController
public class XxxController {

    public void ResponseEntity(ClientRequest clientRequest) {
         ...
         return ResponseEntity.ok(clientResponse);
    }
}

But how can we get the clientResponse object or set a new response body in Spring Boot filter?

@Component
public class MyClassFilter implements Filter {


    @Override
    public void doFilter( HttpServletRequest req,  HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
 
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig arg0) throws ServletException {}

}

Upvotes: 5

Views: 21551

Answers (2)

Subhomoy Sikdar
Subhomoy Sikdar

Reputation: 674

Not sure what you mean by get Response in Filter. In a filter the request is yet to be passed to controller, so there is no response yet. You can get the request though. But be careful not to read the request as in that case the request stream will be read in the filter and when it arrives at the controller the entire request stream will be already read. To set the response you can do the following:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    response.resetBuffer();
    response.setStatus(HttpStatus.OK);
    response.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
    response.getOutputStream().print(new ObjectMapper().writeValueAsString(myData));
    response.flushBuffer(); // marks response as committed -- if we don't do this the request will go through normally!
}

you can see here why you have to flush the response. You can also do sendError HttpServletResponse#sendError How to change ContentType

If you don't flush the response, your request will continue down the filter chain (you have to add the chain.doFilter(request, response); of course!).

Upvotes: 8

MuhammedH
MuhammedH

Reputation: 402

I am not sure with that but I think you can try this :

        HttpServletResponse res = (HttpServletResponse) response;
        ContentCachingResponseWrapper ccrw= new ContentCachingResponseWrapper(res);
        //old body:
        String content=new String(ccrw.getContentAsByteArray(), "utf-8");
        //try this 
        HttpServletResponseWrapper hsrw=new HttpServletResponseWrapper(res);
        hsrw.getOutputStream().write(/*new body*/);
        //OR this 
        ServletResponseWrapper responseWrapper = (ServletResponseWrapper)response;
        responseWrapper.getResponse().resetBuffer();
        responseWrapper.getResponse().getOutputStream().write(/*new body*/);
        

Upvotes: 2

Related Questions