由于 2 天后我仍然无法弄清楚如何在 HttpServletResponse 中执行 HandlerInterceptorAdapter 主体的打印,我会再问一次:)

使用 HttpServletRequest 我可以轻松地做类似 request.getReader().lines().collect(Collectors.joining(System.lineSeparator())); 的事情并且我有完整的 body 但是如何使用 HttpServletResponse 做同样的事情?

我在 StackOverflow 上发现了很多关于这个的问题,但它们似乎都不起作用。

这是处理程序:

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    //how to print here the "response" by using the "response" parameter
    super.afterCompletion(request, response, handler, ex);
}

this 答案完全相同并且链接到 this 但他们使用 ServletResponse 而不是 HttpServletResponse 以及我在 FilterChain 处理程序中没有的带有 afterCompletion 的东西。即使是看起来最完整的 this 也不适合(我认为)在我的情况下。

有人可以为我提供一个带有 HttpServletResponse 的简单序列化示例吗?

最佳答案

很难深入研究它,但发现 ResponseBodyAdvice 可能适合我的目的。因此,在 StackOverflow 上寻找一些示例发现 this 人,他必须操作 Object body 有完全相同的问题。

这是我为了实现我写的 here 的最终工作解决方案

@ControllerAdvice
public class CSRFHandler implements ResponseBodyAdvice<Object> {

    @Value("${security.csrf.enabled}")
    private String csrfEnabled;

    @Value("${security.csrf.headerName}")
    private String csrfHeaderName;

    @Value("${security.csrf.salt}")
    private String salt;

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
            Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
            ServerHttpResponse response) {

        if (new Boolean(csrfEnabled).booleanValue()) {
            String csrfValue = SecureUtil.buildCsrfValue(salt, StringUtil.toJson(body));
            response.getHeaders().add(csrfHeaderName, csrfValue);
        }

        return body;
    }

}

10-07 16:22