业务背景
- 在实际开发过程中,业务上会有很多数据交互和传输,其中必然存在一些敏感数据,不能直接明文传输,需要进行加密
- 前端与后端数据交互时
- 上下游子系统之间交互时
- 本文基于Mybatis结果集ResultSetHandler拦截实现字段加密
一、声明注解
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Encryption {
}
二、加密工具类
public class EncryptionUtil {
public static String Base64Encode(String res) {
return Base64.encode(res.getBytes());
}
public static String Base64Decode(String res) {
return new String(Base64.decode(res));
}
}
三、开启加密
#开启数据加密
encryption=true
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
@Encryption
private String name;
private Integer age;
@Encryption
private String email;
}
四、拦截结果集
@ConditionalOnProperty(value = "encryption", havingValue = "true")
@Intercepts({
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
@Component
public class ResultInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object result = invocation.proceed();
if (Objects.isNull(result)) {
return null;
}
if (result instanceof ArrayList) {
ArrayList resultList = (ArrayList) result;
for (Object obj : resultList) {
encryptionObject(obj);
}
}
else {
encryptionObject(result);
}
return result;
}
private void encryptionObject(Object obj) throws IllegalAccessException {
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getAnnotation(Encryption.class) != null) {
field.setAccessible(true);
Object o = field.get(obj);
if (o != null) {
String encode = EncryptionUtil.Base64Encode(o.toString());
field.set(obj, encode);
}
}
}
}
@Override
public Object plugin(Object o) {
return Plugin.wrap(o, this);
}
@Override
public void setProperties(Properties properties) {
}
}