MyBatis学习笔记-数据脱敏

如果项目需要对一些特殊、敏感的数据进行脱敏处理。根据实际的需求可以考虑在读写的过程中分别做脱敏操作。
一、写过程参数脱敏
主要是使用mybatis框架提供的Interceptor实现。需要考虑不同类型的参数解析处理方式不同。
java 复制代码
@Slf4j
@AllArgsConstructor
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)})
public class ParameterDesensitizationInterceptor extends ParameterInterceptor implements Interceptor {

    private final DesensitizationProperties desensitizationProperties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return handleInvocation(invocation);
    }

    @Override
    public Map<String, List<String>> getObjectFieldsMap() {
        return desensitizationProperties.getObjectFieldsMap();
    }

    @Override
    public Object handleObjectField(Object objectFieldValue) {
        // 暂时只处理字符串类型
        return StringUtils.mask(String.valueOf(objectFieldValue), desensitizationProperties.getStartPosition(),
            desensitizationProperties.getEndPosition(), desensitizationProperties.getMaskChar());
    }

}
java 复制代码
@Slf4j
public abstract class ParameterInterceptor extends AbstractInterceptor {

    /**
     * handle invocation
     * @param invocation
     * @return
     * @throws Throwable
     */
    protected Object handleInvocation(Invocation invocation) throws Throwable {
        ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();
        MetaObject metaObject = MetaObject.forObject(parameterHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
            SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
        Object parameterObject = parameterHandler.getParameterObject();
        if (null == parameterObject) {
            return invocation.proceed();
        }
        Class<Object> parameterizedType = getParameterizedType((MappedStatement) metaObject.getValue("mappedStatement"));
        List<String> fields = getObjectFieldsMap().get(parameterizedType.getName());
        if (null == fields || fields.isEmpty()) {
            return invocation.proceed();
        }
        if (parameterObject instanceof Map) {
            Map<String, Object> parameterMapObject = (Map<String, Object>) parameterObject;
            if (parameterMapObject.containsKey(com.baomidou.mybatisplus.core.toolkit.Constants.ENTITY)) {
                // handle entity object
                Object etObject = parameterMapObject.get(com.baomidou.mybatisplus.core.toolkit.Constants.ENTITY);
                if (null != etObject) {
                    handleObjectFields(etObject);
                }
            } if (parameterMapObject.containsKey(com.baomidou.mybatisplus.core.toolkit.Constants.WRAPPER)) {
                // handle wrapper object
                handleObjectFields(metaObject, fields);
            } else {
                // handle map object
                handleObjectFields(parameterizedType, parameterMapObject);
            }
        } else {
            handleObjectFields(parameterObject);
        }
        return invocation.proceed();
    }

}
二、读过程结果脱敏
主要是使用mybatis框架提供的Interceptor实现。
java 复制代码
@Slf4j
@AllArgsConstructor
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = Statement.class)})
public class ResultSetDesensitizationInterceptor extends ResultSetInterceptor implements Interceptor {

    private final DesensitizationProperties desensitizationProperties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return handleInvocation(invocation);
    }

    @Override
    public Map<String, List<String>> getObjectFieldsMap() {
        return desensitizationProperties.getObjectFieldsMap();
    }

    @Override
    public Object handleObjectField(Object objectFieldValue) {
        // 暂时只处理字符串类型
        return StringUtils.mask(String.valueOf(objectFieldValue), desensitizationProperties.getStartPosition(),
            desensitizationProperties.getEndPosition(), desensitizationProperties.getMaskChar());
    }

}
java 复制代码
@Slf4j
public abstract class ResultSetInterceptor extends AbstractInterceptor {

    /**
     * handle invocation
     * @param invocation
     * @return
     * @throws Throwable
     */
    protected Object handleInvocation(Invocation invocation) throws Throwable {
        Object proceed = invocation.proceed();
        if (null == proceed) {
            return null;
        }
        if (proceed instanceof List) {
            ((List<?>) proceed).forEach(this::handleObjectFields);
        } else {
            handleObjectFields(proceed);
        }
        return proceed;
    }

}

总体来说,数据字段的脱敏操作没有那么复杂,可以根据自身的需求更加细粒度的控制实现。

相关推荐
风象南12 分钟前
SpringBoot配置属性热更新的轻量级实现
java·spring boot·后端
洛阳泰山13 分钟前
Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
java·spring boot·后端·nacos
Y40900113 分钟前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
YuTaoShao14 分钟前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
布朗克16814 分钟前
java常见的jvm内存分析工具
java·jvm·数据库
都叫我大帅哥1 小时前
深入浅出 Resilience4j:Java 微服务的“免疫系统”实战指南
java·spring cloud
Cao_Shixin攻城狮3 小时前
Flutter运行Android项目时显示java版本不兼容(Unsupported class file major version 65)的处理
android·java·flutter
Dcs6 小时前
还在用 Arrays.hashCode?Java 自己也能写出更快的版本!
java
fouryears_234178 小时前
Spring,Spring Boot 和 Spring MVC 的关系以及区别
java·spring boot·spring·mvc
阿葱(聪)8 小时前
java 在k8s中的部署流程
java·开发语言·docker·kubernetes