spring mvc interceptor:访问postHandle中的ResponseEntity

jas*_*son 6 rest spring-mvc interceptor

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

我想从ResponseEntity中获取响应主体和http状态.

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

public void postHandle(HttpServletRequest request, 
    HttpServletResponse response, 
    Object handler, 
    ModelAndView modelAndView) {}
Run Code Online (Sandbox Code Playgroud)

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

谢谢你,杰森

小智 6

当你写下你的问题时,我认为这是不可能的,但现在是不可能的。从他们的文档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 上配置它”


Luc*_*cas 5

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

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


jas*_*son 3

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

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

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

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

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

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