java数据脱敏

1.添加注解DataMaskingClass和注解DataMaskingField分别作用在类和字段上面

/**
 * 需要脱敏的类注解
 *
 */
@Documented
@Inherited
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DataMaskingClass {

}

/**
 * 脱敏字段
 */
@Documented
@Inherited
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataMaskingField {

    /**
     * 脱敏类型
     *
     * @return {@link String}
     */
    MaskingType type() default MaskingType.DEFAULT;

}

2.添加脱敏字段类型

/**
 * 加密类型
 */
public enum MaskingType {

    /**
     * 默认的
     */
    DEFAULT,
    /**
     * 姓名 eg: 李*
     */
    NAME,
    /**
     * 身份证 显示前十位,不足十位的都变为*号
     */
    IDDEN,

    /**
     * 电话 显示前三位和后四位,其他变为*号
     */
    PHONE;
}

3.添加mybatisplus 结果拦截器

/**
 * 结果拦截器
 */
@Slf4j
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class ResultInterceptor implements Interceptor {

    @Autowired
    private IDataMaskingService dataMaskingService;

    @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;
            if (CollectionUtils.isNotEmpty(resultList) && needToMasking(resultList.get(0))) {
                for (Object obj : resultList) {
                    dataMaskingService.masking(obj);
                }
            }
        } else {
            if (needToMasking(result)) {
                dataMaskingService.masking(result);
            }
        }
        return result;
    }

    /**
     * 是否需要脱敏
     *
     * @param object 对象
     * @return boolean
     */
    private boolean needToMasking(Object object) {
        Class<?> objectClass = object.getClass();
        DataMaskingClass encryptDecryptClass = AnnotationUtils.findAnnotation(objectClass, DataMaskingClass.class);
        return Objects.nonNull(encryptDecryptClass);
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

4.添加结果拦截器服务

/**
 * 数据标记服务
 *
 */
public interface IDataMaskingService {

    /**
     * 脱敏
     *
     * @param result 结果
     * @return {@link T}* @throws IllegalAccessException 非法访问异常
     */
    <T> T masking(T result) throws IllegalAccessException;
}



/**
 * 数据标记服务Impl
 *
 */
@Service
public class DataMaskingServiceImpl implements IDataMaskingService {

    /**
     * 脱敏
     *
     * @param result 结果
     * @return {@link T}
     */
    @Override
    public <T> T masking(T result) throws IllegalAccessException {
        Class<?> parameterObjectClass = result.getClass();
        Field[] declaredFields = parameterObjectClass.getDeclaredFields();
        for (Field field : declaredFields) {
            DataMaskingField annotation = field.getAnnotation(DataMaskingField.class);
            if (Objects.isNull(annotation)) {
                continue;
            }
            MaskingType type = annotation.type();
            //允许通过反射访问该字段
            field.setAccessible(true);
            //返回指定对象result上此field表示的字段的值
            Object object = field.get(result);
            String value = MaskingUtils.getValue(object, type);
            field.set(result, value);
        }
        return result;
    }
}

5 .MybatisPlusConfig里面注入结果拦截器

/**
     * 脱敏拦截器
     *
     * @return {@link ResultInterceptor}
     */
    @Bean
    @ConditionalOnMissingBean
    public ResultInterceptor resultInterceptor() {
        return new ResultInterceptor();
    }

备注:脱敏工具类

/**
 * 脱敏工具类
 */
public class MaskingUtils {

    /**
     * 获得的脱敏值
     *
     * @param object 对象
     * @param type   类型
     * @return {@link String}
     */
    public static String getValue(Object object, MaskingType type) {
        String value = (String) object;
        switch (type) {
            case DEFAULT:
                if (Assert.isNotBlank(value)) {
                    value = "********";
                }
                break;
            case NAME:
                if (Assert.isNotBlank(value)) {
                    value = value.substring(0, 1) + value.substring(1).replaceAll(".", "*");
                }
                break;
            case IDDEN:
                if (value != null && !"".equals(value)) {
                    value = value.toUpperCase();
                    value = value.replaceAll("(\\d{4})\\d{10}([0-9X]{4})", "$1********$2");
                }
                break;
            case PHONE:
                if (value != null && !"".equals(value)) {
                    value = value.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
                }
                break;
            default:
                break;
        }
        return value;
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值