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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
实现的示例:
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
这样得到的处理过的返回值,属性xxx的值都是“测试修改返回值”;