我们如何在 Spring Boot Filter 中获取和设置响应主体?

lzk*_*234 5 java spring spring-mvc web spring-boot

我有一个 Spring MVC 应用程序,它返回ResponseEntityclientResponse对象作为响应主体:

@RestController
public class XxxController {

    public void ResponseEntity(ClientRequest clientRequest) {
         ...
         return ResponseEntity.ok(clientResponse);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我们如何clientResponse在 Spring Boot 过滤器中获取对象或设置新的响应主体呢?

@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 {}

}
Run Code Online (Sandbox Code Playgroud)

Sub*_*dar 7

不确定在过滤器中获取响应是什么意思。在过滤器中,请求尚未传递到控制器,因此还没有响应。不过您可以收到请求。但请注意不要读取请求,因为在这种情况下,请求流将在过滤器中读取,并且当它到达控制器时,整个请求流将已被读取。要设置响应,您可以执行以下操作:

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!
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到为什么你必须刷新响应。您还可以执行sendError HttpServletResponse#sendError 如何更改 ContentType

如果您不刷新响应,您的请求将继续沿着过滤器链向下(chain.doFilter(request, response);当然您必须添加!)。


Muh*_*edH 2

我不确定,但我想你可以尝试这个:

        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*/);
        
Run Code Online (Sandbox Code Playgroud)