@ControllerAdvice,ResponseBodyAdvice 統一處理返回值/響應體
阿新 • • 發佈:2019-02-12
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的值都是“測試修改返回值”;