【问题标题】:How can we get and set response body in Spring Boot Filter我们如何在 Spring Boot Filter 中获取和设置响应体
【发布时间】:2020-11-09 04:07:29
【问题描述】:

我有一个 Spring MVC 应用程序,它返回 ResponseEntity 和 clientResponse 对象作为响应体

@RestController
public class XxxController {

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

但是我们如何在 Spring Boot Filter 中获取 clientResponse 对象或者设置一个新的 Response body 呢?

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

}

【问题讨论】:

    标签: java spring spring-boot spring-mvc web


    【解决方案1】:

    我不确定,但我认为你可以试试这个:

            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*/);
            
    

    【讨论】:

    • 使用上面的ccrw可以做到ccrw.resetBuffer();ccrw.getOutputStream().write(<bytes>);crw.copyBodyToResponse();
    【解决方案2】:

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

    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!
    }
    

    你可以在这里看到为什么你必须刷新响应。你也可以sendErrorHttpServletResponse#sendError How to change ContentType

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 2017-12-27
    • 2016-04-24
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    相关资源
    最近更新 更多