@ControllerAdvice,ResponseBodyAdvice 统一处理返回值/响应体

ResponseBodyAdvice是spring4.1的新特性,其作用是在响应体写出之前做一些处理;比如,修改返回值、加密等。

我在项目中的用到@ControllerAdvice,ResponseBodyAdvice的目的,是为每个请求的返回json中修改一个属性值。

package org.springframework.web.servlet.mvc.method.annotation; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; /**  * Allows customizing the response after the execution of an {@code @ResponseBody}  * or an {@code ResponseEntity} controller method but before the body is written  * with an {@code HttpMessageConverter}. Implementations may be may be registered directly with  * {@code RequestMappingHandlerAdapter} and {@code ExceptionHandlerExceptionResolver}  * or more likely annotated with {@code @ControllerAdvice} in which case they  * will be auto-detected by both.  *  * @author Rossen Stoyanchev  * @since 4.1  */ public interface ResponseBodyAdvice {     /**      * Whether this component supports the given controller method return type      * and the selected {@code HttpMessageConverter} type.      * @param returnType the return type      * @param converterType the selected converter type      * @return {@code true} if {@link #beforeBodyWrite} should be invoked, {@code false} otherwise      */     boolean supports(MethodParameter returnType, Class> converterType);      /**      * Invoked after an {@code HttpMessageConverter} is selected and just before      * its write method is invoked.      * @param body the body to be written      * @param returnType the return type of the controller method      * @param selectedContentType the content type selected through content negotiation      * @param selectedConverterType the converter type selected to write to the response      * @param request the current request      * @param response the current response      * @return the body that was passed in or a modified, possibly new instance      */     T beforeBodyWrite(T body, MethodParameter returnType, MediaType selectedContentType,             Class> selectedConverterType,             ServerHttpRequest request, ServerHttpResponse response);  } 
package com.xxx; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import com.xxx.Messages; /**  * 处理 返回值  * @Description:TODO  * @author lh  * @time:2015-8-31 上午11:24:08  */  @ControllerAdvice public class MyResponseBodyAdvice implements ResponseBodyAdvice{      @Override     public Object beforeBodyWrite(Object returnValue, MethodParameter methodParameter,             MediaType mediaType, Class clas, ServerHttpRequest serverHttpRequest,             ServerHttpResponse serverHttpResponse) {         //通过 ServerHttpRequest的实现类ServletServerHttpRequest 获得HttpServletRequest           //ServletServerHttpRequest sshr=(ServletServerHttpRequest) serverHttpRequest;         //此处获取到request 是为了取到在拦截器里面设置的一个对象 是我项目需要,可以忽略         //HttpServletRequest request=   sshr.getServletRequest();          //将返回值returnValue转成我需要的类型Message<?>  方便统一修改其中的某个属性           // Messages是我自定义的一个类        Messages<?> msg=(Messages<?>) returnValue;         //统一修改返回值/响应体         msg.setXXX("测试修改返回值");         //返回修改后的值         return msg;     }      @Override     public boolean supports(MethodParameter methodParameter, Class clas) {         //获取当前处理请求的controller的方法         String methodName=methodParameter.getMethod().getName();          // 不拦截/不需要处理返回值 的方法         String method= "loginCheck"; //如登录         //不拦截         return !method.equals(methodName);     } } 

这样得到的处理过的返回值,属性xxx的值都是“测试修改返回值”;