ResponseBodyAdvice接口是在Controller執行return之后,在response返回給瀏覽器或者APP客戶端之前,執行的對response的一些處理。可以實現對response數據的一些統一封裝或者加密等操作。
該接口一共有兩個方法:
@Override //判斷是否要執行beforeBodyWrite方法,true為執行,false不執行 public boolean supports(MethodParameter returnType, Class converterType) { return false; } @Override //對response處理的執行方法 public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { return null; }
通過supports方法,我們可以選擇哪些類,或者哪些方法要對response進行處理,其余的則不處理。
beforeBdoyWrite方法中,為對response處理的具體代碼。
實例:有一個工程,這個工程中的一個Controller類,返回參數為OutputObject(一個自定義的javaBean),我們要通過ResponseBodyAdvice,對該類的所有方法返回的OutputObject中的部分數據進行統一加密處理。
package com.cmos.edcreg.web.intercepter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.stereotype.Component; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import com.alibaba.fastjson.JSON; import com.cmos.edcreg.beans.common.OutputObject; import com.cmos.edcreg.utils.StringUtil; import com.cmos.edcreg.utils.des.DesSpecial; import com.cmos.edcreg.utils.enums.ReturnInfoEnums; import com.fasterxml.jackson.databind.ObjectMapper; /** * 對響應報文統一處理,對bean內容進行加密 * @author qiaozhong */ @Component //聲明該類要處理的包路徑 @ControllerAdvice("com.cmos.edcreg.web.controller") public class ResponseAdvice implements ResponseBodyAdvice { private final Logger logger = LoggerFactory.getLogger(ResponseAdvice.class); /* * 對response處理的具體方法 * arg0為返回的報文體,arg0為org.json.jsonObject,使用alibaba.json方法轉換時候報錯了 */ @Override public Object beforeBodyWrite(Object arg0, MethodParameter arg1, MediaType arg2, Class arg3, ServerHttpRequest arg4, ServerHttpResponse arg5) { OutputObject out = new OutputObject(); try { //arg0轉換為OutputObject類型 ObjectMapper objectMapper=new ObjectMapper(); out = objectMapper.readValue(org.json.JSONObject.valueToString(arg0), OutputObject.class); //獲取加密密鑰 String oldEncryptKey = out.getBean().get("oldEncryptKey"); //獲取加密字符串 DesSpecial des = new DesSpecial(); String encryptData = des.strEnc(JSON.toJSONString(out.getBean()), oldEncryptKey, null, null); //封裝數據(清除原來數據,放入加密數據) out.getBean().clear(); out.getBean().put("data", encryptData); return out; } catch (Exception e) { logger.error("返回報文處理出錯", e); out.setReturnCode(ReturnInfoEnums.PROCESS_ERROR.getCode()); out.setReturnMessage(ReturnInfoEnums.PROCESS_ERROR.getMessage()); return out; } } /* * 選擇哪些類,或哪些方法需要走beforeBodyWrite * 從arg0中可以獲取方法名和類名 * arg0.getMethod().getDeclaringClass().getName()為獲取方法名 */ @Override public boolean supports(MethodParameter arg0, Class arg1) { if("com.cmos.edcreg.web.controller.GdH5AppointmentActiveVideoNewController".equals(arg0.getMethod().getDeclaringClass().getName())){ return true; }else{ return false; } } }