Spring MVC 中 Json 响应的后处理

Posted

技术标签:

【中文标题】Spring MVC 中 Json 响应的后处理【英文标题】:Post processing of a Json response in spring MVC 【发布时间】:2014-11-05 12:06:04 【问题描述】:

我有几个控制器使用@ResponseBody 注释返回相同的通用响应对象,如下所示:

@RequestMapping(value = "/status", method = RequestMethod.GET)
    @Transactional(readOnly = true)
    public @ResponseBody Response<StatusVM> status()

在返回响应后,我需要对每个控制器执行操作。此操作将使用新数据丰富 Response 对象。

我不想重复代码,所以我需要单点干预。我以为我可以用拦截器来做到这一点,但是,根据文档http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor 这不适用于@ResponseBody:

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

我找不到这种技术的例子,有人可以帮助我吗?

作为替代方案,我可以使用方面,但是我需要注释每个控制器,这是我想避免的。

【问题讨论】:

【参考方案1】:

最后我这样实现了 ResponseBodyAdvice:

@ControllerAdvice
public class StatusAdvice implements ResponseBodyAdvice<Response<?>> 


    @Override
    public boolean supports(MethodParameter returnType,
            Class<? extends HttpMessageConverter<?>> converterType) 

        if (returnTypeIsReponseVM(returnType)&&responseConverterIsJackson2(converterType))
            return true;
        

        return false;
    

....

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

        ....

        return body;
    


所以比预期的要容易。

【讨论】:

甜蜜!只是制作这个ResponseBodyAdvice&lt;Object&gt;if (body == null) response.setStatus(HttpStatus.NO_CONTENT); 似乎有效。你能想到为什么这不起作用的任何原因吗? (即:在 BAD_REQUEST、INTERNAL_SERVER_ERROR 或类似情况的情况下?)不幸的是,没有response.getStatus(),所以在将其设置为 NO_CONTENT 之前,我也无法检查 OK 的状态。 :( @ShadowMan 我没有相关代码了,但是能够从另一个项目中检索到类似的东西。当状态不正常时,响应正文应为空。在这种情况下,响应应该始终是 ServletServerHttpResponse 的一个实例,因此如果您必须获取响应状态,那么这样的事情应该可以工作:if (response instanceof ServletServerHttpResponse) ((ServletServerHttpResponse)response).getServletResponse().getStatus();

以上是关于Spring MVC 中 Json 响应的后处理的主要内容,如果未能解决你的问题,请参考以下文章

spring mvc怎么返回json

Spring MVC 学习笔记 --- [SpringMVC的数据响应(Ajax提交请求后,用JSON格式响应数据)]

spring mvc 休息响应 json 和 xml

Spring 4 mvc REST XML 和 JSON 响应

spring mvc返回json字符串的方式

Spring MVC 测试,MockMVC:方便地将对象与 JSON 进行转换