概述
数据落库自动加解密
- 注解
- 逻辑切面
注解
/**
* @author: guanjian
* @date: 2020/07/18 8:09
* @description: 数据保护注解(方法注解)
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataProtect {
}
/**
* @author: guanjian
* @date: 2020/07/18 8:09
* @description: 对称解密
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Decrypt {
}
/**
* @author: guanjian
* @date: 2020/07/18 8:09
* @description: 对称加密
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Encrpty {
}
逻辑切面
/**
* @author: guanjian
* @date: 2020/07/18 8:12
* @description: 数据保护处理
*/
@Aspect
@Component("dataProtectAspect")
public class DataProtectAspect {
@Resource
private AksRpc aksRpc;
@Around("@annotation(xxx.service.aspect.annotation.DataProtect)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Assert.notEmpty(pjp.getArgs(), "args can not be null.");
Stream.of(pjp.getArgs()).forEach(arg -> {
if (arg instanceof Collection) {
Collection collection = (Collection) arg;
collection.forEach(x -> handleObject(x));
} else {
handleObject(arg);
}
});
Object result = pjp.proceed();
if (result instanceof Collection) {
Collection collection = (Collection) result;
collection.forEach(x -> {
handleObject(x);
});
} else {
handleObject(result);
}
return result;
}
/**
* 处理属性对象
*
* @param arg 对象
* @return
*/
private void handleObject(Object arg) {
Optional.ofNullable(arg)
.map(Object::getClass)
.map(Class::getDeclaredFields)
.ifPresent(fields ->
Stream.of(fields)
.forEach(field -> {
try {
//放行未注解加解密字段
if (!field.isAnnotationPresent(Encrpty.class) && !field.isAnnotationPresent(Decrypt.class)) return;
//过滤属性为空
field.setAccessible(true);
Object value = field.get(arg);
if (Objects.isNull(value)) return;
//属性为对象,进行递归
if (isParseByObject(value.getClass())) {
handleObject(value);
}
//属性为字段
else {
handleField(field, arg);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}));
}
/**
* 解析字段属性
*
* @param field 字段
* @param arg 对象
* @return
*/
private void handleField(Field field, Object arg) {
//仅处理字符串类型字段
if (field.getType() != String.class) return;
if (field.isAnnotationPresent(Encrpty.class)) {
try {
field.setAccessible(true);
Object value = field.get(arg);
if (StringUtils.isBlank((CharSequence) value)) return;
String ciphertext = aksRpc.encryptString(String.valueOf(value));
field.set(arg, ciphertext);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (field.isAnnotationPresent(Decrypt.class)) {
try {
field.setAccessible(true);
Object value = field.get(arg);
if (StringUtils.isBlank((CharSequence) value)) return;
String ciphertext = aksRpc.decryptString(String.valueOf(value));
field.set(arg, ciphertext);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
private boolean isParseByObject(Class clz) {
try {
return !clz.isPrimitive()
&& clz != Date.class
&& clz != BigDecimal.class
&& clz != BigInteger.class
&& !isWrapClass(clz)
&& clz != String.class;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static boolean isWrapClass(Class clz) {
try {
return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
} catch (Exception e) {
return false;
}
}
}
最后
以上就是明亮糖豆为你收集整理的数据落库自动加解密实现注解逻辑切面的全部内容,希望文章能够帮你解决数据落库自动加解密实现注解逻辑切面所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复