您的位置:首页 > 编程语言 > Java开发

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

2016-12-23 11:15 1586 查看
ResponseBodyAdvice是spring4.1的新特性,其作用是在响应体写出之前做一些处理;比如,修改返回值、加密等。

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

ResponseBodyAdvice 接口源码:

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的值都是“测试修改返回值”;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息