6

我有一个记录 Spring MVC 响应结果的拦截器。我的所有响应都返回具有 JSON 正文内容的 ResponseEntity 对象。

我想从 ResponseEntity 中获取响应正文和 http 状态。

如何从 postHandle 方法属性访问 ResponseEntity?

public void postHandle(HttpServletRequest request, 
    HttpServletResponse response, 
    Object handler, 
    ModelAndView modelAndView) {}

对于我的调用,modelAndView 属性为 null。

谢谢,杰森

4

3 回答 3

4

当您写下您的问题时,我认为这是不可能的,但现在是。从他们的文档http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-intercepto

“请注意,HandlerInterceptor 的 postHandle 方法并不总是非常适合与 @ResponseBody 和 ResponseEntity 方法一起使用。在这种情况下,HttpMessageConverter 在调用 postHandle 之前写入并提交响应,这使得无法更改响应,例如添加一个标头。相反,应用程序可以实现 ResponseBodyAdvice 并将其声明为 @ControllerAdvice bean 或直接在 RequestMappingHandlerAdapter 上配置它”

于 2016-07-20T11:34:19.367 回答
3
@ControllerAdvice
public class ResponseDTOFilterAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(final MethodParameter returnType, final Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(final Object body, final MethodParameter returnType, final MediaType selectedContentType,
        final Class<? extends HttpMessageConverter<?>> selectedConverterType, final ServerHttpRequest request,
        final ServerHttpResponse response) {
        if (body instanceof ResponseDTO<?>) {
            ResponseDTO<?> responseDTO = (ResponseDTO<?>) body;
            responseDTO.setHostname(request.getLocalAddress().getHostName());
        }
        return body;
    }
}

来源:Spring MVC 中 Json 响应的后处理

于 2017-05-24T17:48:14.497 回答
2

我找到了一个完整的解决方案和一个部分的解决方案。

部分解决方案:对于那些使用 Servlet 3.0 的用户,HTTPStatus 代码在 HttpServletResponse 对象上可用。这将解决我的问题的一半,因为我可以获得状态代码,但它仍然没有让我访问具有我想要检查的 body 属性的 ResponseEntity。

完整解决方案(适用于 Servlet 2.x):我使用了 Aspect 和 Interceptor 的组合。

Aspect 被编码为针对返回 ResponseEntities 的控制器方法的 @AfterReturn。它基本上捕获了返回的 responseEntity 并将其放入 ThreadLocal<ResponseEntity> 集合中。

然后拦截器向 Aspect 询问线程的响应,并且 TA-DAH 可以访问它。

我希望这个答案对其他人有所帮助。干杯,杰森

于 2012-04-19T22:02:40.390 回答