org.zodiac.mybatisplus.interceptor.ProtectInterceptor Maven / Gradle / Ivy
package org.zodiac.mybatisplus.interceptor;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.zodiac.commons.support.SpringContextHolder;
import org.zodiac.core.data.ProtectFieldHandler;
import org.zodiac.core.exception.IllegalUsageException;
import org.zodiac.mybatisplus.binding.parser.ParserCache;
import org.zodiac.sdk.toolkit.util.lang.ObjUtil;
import org.zodiac.sdk.toolkit.util.lang.StrUtil;
import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 数据保护拦截器。
*
*/
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class ProtectInterceptor implements Interceptor {
private ProtectFieldHandler protectFieldHandler;
public ProtectInterceptor() {}
public ProtectInterceptor(ProtectFieldHandler protectFieldHandler) {
this.protectFieldHandler = protectFieldHandler;
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
if (args.length > 1) {
MappedStatement mappedStatement = (MappedStatement)args[0];
SqlCommandType sqlType = mappedStatement.getSqlCommandType();
if (SqlCommandType.INSERT == sqlType || SqlCommandType.UPDATE == sqlType) {
Object entity = args[1];
Configuration config = mappedStatement.getConfiguration();
if (entity instanceof Map) {
Set set = new HashSet<>();
for (Map.Entry, ?> entry : ((Map, ?>)entity).entrySet()) {
Object value = entry.getValue();
if (value == null || value instanceof Wrapper || set.contains(value.hashCode())) {
continue;
}
set.add(value.hashCode());
if (value instanceof List) {
for (Object obj : (List>)value) {
if (!encryptor(config, obj, true)) {
break;
}
}
} else {
encryptor(config, value, true);
}
}
} else {
encryptor(config, entity, true);
}
}
return invocation.proceed();
} else {
ResultSetHandler resultSetHandler = (ResultSetHandler)invocation.getTarget();
Field field = resultSetHandler.getClass().getDeclaredField("mappedStatement");
field.setAccessible(true);
List> list = (List>)invocation.proceed();
if (list.isEmpty()) {
return list;
}
Configuration config = ((MappedStatement)field.get(resultSetHandler)).getConfiguration();
for (Object obj : list) {
if (!encryptor(config, obj, false)) {
break;
}
}
return list;
}
}
@Override
public Object plugin(Object obj) {
return obj instanceof Executor || obj instanceof ResultSetHandler ? Plugin.wrap(obj, this) : obj;
}
/**
* 数据处理。
*
* @param config 配置
* @param entity 对象
* @param isEncrypt 是否加密
* @return 是否进行了处理
*/
private boolean encryptor(Configuration config, Object entity, boolean isEncrypt) {
Class> clazz = entity.getClass();
List protectFieldList = ParserCache.getProtectFieldList(clazz);
if (!protectFieldList.isEmpty()) {
MetaObject metaObject = config.newMetaObject(entity);
ProtectFieldHandler handler = ObjUtil.defaultIfNull(this.protectFieldHandler,
SpringContextHolder.getBean(ProtectFieldHandler.class));
if (handler == null) {
throw new IllegalUsageException("未找到 %s 对象。", ProtectFieldHandler.class.getSimpleName());
}
protectFieldList.forEach(fieldName -> {
String value = StrUtil.stringValueOf(metaObject.getValue(fieldName));
if (value != null) {
metaObject.setValue(fieldName, isEncrypt ? protectFieldHandler.encrypt(clazz, fieldName, value)
: protectFieldHandler.decrypt(clazz, fieldName, value));
}
});
}
return !protectFieldList.isEmpty();
}
}