前言:
日常開發中,我們常常需要對@RequestBody的參數進行各種處理,例如加解密、打印日誌,這些東西我們可以用到RequestBodyAdvice 和 ResponseBodyAdvice來對請求前後進行處理,本質上他倆都是AOP,這裏做加解密處理記錄。
1 RequestBodyAdvice
@RestControllerAdvice
public class CustomRequestControllerAdvice implements RequestBodyAdvice {
}
RequestBodyAdvice接口中提供了四個實現方法:
(1)supports:返回true代表開啓支持,false不支持。
(2)beforeBodyRead:body讀取前進行處理。
(3)afterBodyRead:body讀取後進行處理。
(4)handleEmptyBody:body爲空時處理。
這裏使用beforeBodyRead進行解密處理演示:
定義一個內部類,通過構造參數進行處理
/**
* @author:lis
* @createTime:2019-11-08 10:42
* @description:內部類處理header和body數據解密
* @modifyTime:
* @modifyDescription:
*/
class CustomHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
public CustomHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
//TODO 此處header解密處理
headers = inputMessage.getHeaders();
/**
* 這裏有個嚴重聲明!!!
* IOUtils.toString(inputMessage.getBody(), "UTF-8")取完數據後一定需要緩存!!
* 寫法如下:
*/
String bodyStr = IOUtils.toString(inputMessage.getBody(), "UTF-8");
//TODO 此處body解密處理
String data = AESUtil.decrypt(bodyStr,environment.getProperty("dataKey"),environment.getProperty("dataOffset"));
body = IOUtils.toInputStream(data, "UTF-8");
}
public InputStream getBody() {
return this.body;
}
public HttpHeaders getHeaders() {
return this.headers;
}
}
注意:上述代碼中的聲明,因爲requestBody的數據是通過流來獲取的,所以在使用HttpInputMessage獲取數據後,一定要記錄下來,放回去記錄的,因爲該數據只能取一次,第二次獲取將返回NULL!
2 ResponseBodyAdvice
ResponseBodyAdvice接口提供了兩種實現方法
(1)supports:返回true代表開啓支持,false不支持。
(2)beforeBodyWrite:body返回給頁面參數之前處理。
這裏的beforeBodyWrite可用於返回數據加密處理,業務代碼不做演示了。