RequestBodyAdvice可以了解為在@RequestBody之前需要進行的 操作,ResponseBodyAdvice可以了解為在@ResponseBody之後進行的操作,是以當接口需要加解密時,在使用@RequestBody接收前台參數之前可以先在RequestBodyAdvice的實作類中進行參數的解密,當操作結束需要傳回資料時,可以在@ResponseBody之後進入ResponseBodyAdvice的實作類中進行參數的加密。
先來看一下源碼RequestBodyAdvice
public interface RequestBodyAdvice {
boolean supports(MethodParameter methodParameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType);
Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException;
Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
}
再來看一下源碼RequestBodyAdvice
public interface ResponseBodyAdvice<T> {
boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
T beforeBodyWrite(T body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response);
}
///
完成加密解密的操作
首先自定義一個注解類(用來後期判斷是否使用加解密)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Encrypt {
}
加密時需要建立一個ParamEncryptResponseBodyAdvice類繼承于ResponseBodyAdvice
@ControllerAdvice
public class ParamEncryptResponseBodyAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return returnType.hasMethodAnnotation(Encrypt.class);//判斷是否支援加密,必須有@Encrypt注解才支援
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
org.springframework.http.MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
System.out.println("此處進行資料加密");
return body;
}
}
解密需要建立一個類繼承于RequestBodyAdvice
@ControllerAdvice
public class ParamDecryptRequestBodyAdvice implements RequestBodyAdvice {
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return methodParameter.hasParameterAnnotation(Encrypt.class);//判斷解密。必須使用@Encrypt注解才進行解密
}
public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
public HttpInputMessage beforeBodyRead( HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
return new HttpInputMessage() {
public InputStream getBody() throws IOException {
System.out.println("此處進行解密");
return new ByteArrayInputStream();
}
public HttpHeaders getHeaders() {
return httpInputMessage.getHeaders();
}
};
}
public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
}
在controller層調用時
1.不加密不解密
@PostMapping("/search")
@ResponseBody
public ResultForSearch searchTicket(@RequestBody SearchReq_Param search_Param){
return null;
}
2.加密解密
@PostMapping("/search")
@ResponseBody
@Encrypt
public ResultForSearch searchTicket(@[email protected] SearchReq_Param search_Param){
return null;
}
3.隻加密不解密
@PostMapping("/search")
@ResponseBody
@Encrypt
public ResultForSearch searchTicket(@RequestBody SearchReq_Param search_Param){
return null;
}