1 自定义注解 该注解放在作用再controller上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface EncryptFilter {
/**
* 对入参是否解密
* @return
*/
boolean decryptRequest() default true;
/**
* 对出参是否加密
*/
boolean encryptResponse() default true;
}
2 对请求数据进行数据处理
/**
* 接口入参解密
* RequestBodyAdvice可以理解为在@RequestBody之前需要进行的 *** 作,
* ResponseBodyAdvice可以理解为在@ResponseBody之后进行的 *** 作;
* 所以当接口需要加解密时,在使用@RequestBody接收前台参数之前可以先在RequestBodyAdvice的实现类中进行参数的解密,
* 当 *** 作结束需要返回数据时,可以在@ResponseBody之后进入ResponseBodyAdvice的实现类中进行参数的加密。
*/
@RestControllerAdvice
@Slf4j
public class DecryptRequestBodyAdapter extends RequestBodyAdviceAdapter {
/**
* 该方法用于判断当前请求,是否要执行beforeBodyRead方法
*
* @param methodParameter handler方法的参数对象
* @param targetType handler方法的参数类型
* @param converterType 将会使用到的Http消息转换器类类型
* @return 返回true则会执行beforeBodyRead
*/
@Override
public boolean supports(MethodParameter methodParameter, Type targetType,
Class extends HttpMessageConverter>> converterType) {
Method method = methodParameter.getMethod();
if (Objects.nonNull(method)) {
EncryptFilter encryptFilter = method.getAnnotation(EncryptFilter.class);
if (Objects.nonNull(encryptFilter)) {
return encryptFilter.decryptRequest();
}
}
return false;
}
/**
* 在Http消息转换器执转换,之前执行
*
* @param inputMessage 客户端的请求数据
* @param methodParameter handler方法的参数对象
* @param targetType handler方法的参数类型
* @param converterType 将会使用到的Http消息转换器类类型
* @return 返回 一个自定义的HttpInputMessage
*/
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type targetType,
Class extends HttpMessageConverter>> converterType) throws IOException {
// 读取加密的请求体
InputStream body = inputMessage.getBody();
HttpHeaders headers = inputMessage.getHeaders();
headers.remove("Content-Length");
String s = StreamUtil.getBodyString(body);
log.info("解密前请求body:" + s);
if (Strings.isNotEmpty(s)) {
// 使用sm4解密
String bodyDec = null;
try {
bodyDec = Sm4Util.decryptEcb(Constants.KEY,s);
} catch (Exception e) {
e.printStackTrace();
}
log.info("解密后请求body:" + bodyDec);
if (Strings.isNotEmpty(bodyDec)) {
// 使用解密后的数据,构造新的读取流
InputStream inputStream = new ByteArrayInputStream(bodyDec.getBytes(StandardCharsets.UTF_8));
return new HttpInputMessage() {
@Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
@Override
public InputStream getBody() {
return inputStream;
}
};
}
}
return inputMessage;
}
3 对返回结果进行数据加密 继承ResponseBodyAdvice
/**
* 接口出参加密
* RequestBodyAdvice可以理解为在@RequestBody之前需要进行的 *** 作,
* ResponseBodyAdvice可以理解为在@ResponseBody之后进行的 *** 作;
* 所以当接口需要加解密时,在使用@RequestBody接收前台参数之前可以先在RequestBodyAdvice的实现类中进行参数的解密,
* 当 *** 作结束需要返回数据时,可以在@ResponseBody之后进入ResponseBodyAdvice的实现类中进行参数的加密。
*/
//@RestControllerAdvice("com.example.springbootEncrypt.controller")
// 表示com.example.springbootEncrypt.controller此包下的所有响应对象都会经过此拦截器,并对响应体加密
@RestControllerAdvice
@Slf4j
public class EncryptResponseBodyAdapter implements ResponseBodyAdvice
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)