接口源码
//ResponseBodyAdvice接口
public interface ResponseBodyAdvice<T> {
boolean supports(MethodParameter var1,
Class<? extends HttpMessageConverter<?>> var2);
@Nullable
T beforeBodyWrite(@Nullable T var1,
MethodParameter var2,
MediaType var3,
Class<? extends HttpMessageConverter<?>> var4,
ServerHttpRequest var5,
ServerHttpResponse var6);
}
//RequestBodyAdvice 接口
public interface RequestBodyAdvice {
boolean supports(MethodParameter var1,
Type var2,
Class<? extends HttpMessageConverter<?>> var3);
HttpInputMessage beforeBodyRead(HttpInputMessage var1,
MethodParameter var2,
Type var3,
Class<? extends HttpMessageConverter<?>> var4)
throws IOException;
Object afterBodyRead(Object var1,
HttpInputMessage var2,
MethodParameter var3,
Type var4,
Class<? extends HttpMessageConverter<?>> var5);
@Nullable
Object handleEmptyBody(@Nullable Object var1,
HttpInputMessage var2,
MethodParameter var3,
Type var4,
Class<? extends HttpMessageConverter<?>> var5);
}
使用场景
RequestBodyAdvice一般使用是处理解密json串,而ResponseBodyAdvice是一般使用是处理加密字符串。
执行机制
1.RequestBodyAdvice
需在Controller层中的方法上加上@RequestMapping和@RequestBody;若是没有@RequestBody,
RequestBodyAdvice则不会执行。
2.ResponseBodyAdvice
需在controller层中的方法上加上@RequestMapping和ResponseBody;若是没有@ResponseBody,
ResponseBodyAdvice不会执行。
运用
1.准备自定义注解
@Target(Element.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt{
// do nothing,this is just a mark
}
2.实现接口类
@Slf4j
@RestControllerAdvice
public class ParamEncryptResponseBodyAdvice implements ResponseBodyAdvice {
@Value("${public.clientKey}")
private String clientKey;
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
boolean support = methodParameter.hasMethodAnnotation(Encrypt.class);
return support;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
MediaType mediaType,
Class aClass, ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {
log.info("开始数据加密");
String jsonStr = JSON.toJSONString(o);
log.info("加密数据:{}", jsonStr);
/* 使用加密算法进行加密:
* RSA(非对称加密,公钥加密,私钥解密),
* AES(对称加密,加密解密同一个规则,采用4x4字节矩阵加密)
**/
String encryptStr = RSAUtils.encrypt(jsonStr,clientKey);
log.info("加密结果:{}", encryptStr);
return JSON.parseObject(encryptStr);
}
}
//解密
@Slf4j
@RestControllerAdvice
public class ParamDecryptRequestBodyAdvice implements RequestBodyAdvice {
@Value("${private.clientKey}")
private String clientKey;
@Override
public boolean supports(MethodParameter methodParameter,
Type type, Class<? extends HttpMessageConverter<?>> aClass) {
//return false does not execute
return methodParameter.hasParameterAnnotation(
RequestBody.class) &&
methodParameter.hasMethodAnnotation(Encrypt.class);
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage,
MethodParameter methodParameter,
Type type,
Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
try {
String inputString = IOUtils.inputStream2String(httpInputMessage.getBody());
log.info("接收到解密请求:{}",inputString);
try{
JSONObject jsonObject = JSON.parseObject(inputString);
if(jsonObject.containsKey("requsetData")){
String encryptStr = jsonObject.getString("requsetData");
String decryptStr = RSAUtils.decrypt(encryptStr,clientKey);
}
}catch (JSONException e){
log.error("解密出错,JSON解析异常:{}",e);
e.printStackTrace();
}catch (ClassCastException e){
log.error("解密出错,JSON解析异常:{}",e);
e.printStackTrace();
}
}catch (IOException e){
log.error("解密出错:{}",e);
e.printStackTrace();
}
return httpInputMessage.getBody();
}
@Override
public HttpHeaders getHeaders() {
return httpInputMessage.getHeaders();
}
};
}
@Override
public Object afterBodyRead(Object o,
HttpInputMessage httpInputMessage,
MethodParameter methodParameter,
Type type,
Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
@Override
public Object handleEmptyBody(Object o,
HttpInputMessage httpInputMessage,
MethodParameter methodParameter,
Type type,
Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
}