diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java index a0a571acc..3d1642803 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java @@ -1,47 +1,117 @@ package org.dromara.common.encrypt.interceptor; import lombok.AllArgsConstructor; +import org.apache.ibatis.cursor.Cursor; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.*; import org.dromara.common.encrypt.core.EncryptedFieldProcessor; +import java.io.IOException; import java.sql.Statement; +import java.util.Iterator; import java.util.Properties; /** * 出参解密拦截器 * - * @author 老马 - * @version 4.6.0 + * @author Lion Li */ -@Intercepts({@Signature( - type = ResultSetHandler.class, - method = "handleResultSets", - args = {Statement.class}) +@Intercepts({ + @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}), + // MP 3.5.17 起 selectOne/selectVoOne 走游标,需一并拦截解密 + @Signature(type = ResultSetHandler.class, method = "handleCursorResultSets", args = {Statement.class}) }) @AllArgsConstructor public class MybatisDecryptInterceptor implements Interceptor { private final EncryptedFieldProcessor encryptedFieldProcessor; + /** + * 解密 MyBatis 查询结果中的加密字段。 + * + * @param invocation 拦截调用信息 + * @return 查询结果 + * @throws Throwable 拦截处理异常 + */ @Override public Object intercept(Invocation invocation) throws Throwable { - // 获取执行mysql执行结果 Object result = invocation.proceed(); if (result == null) { return null; } + if (result instanceof Cursor cursor) { + return new DecryptCursor<>(cursor, encryptedFieldProcessor); + } encryptedFieldProcessor.decrypt(result); return result; } + /** + * 包装 MyBatis 目标对象。 + * + * @param target 目标对象 + * @return 包装后的对象 + */ @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } + /** + * 设置插件属性。 + * + * @param properties 插件属性 + */ @Override public void setProperties(Properties properties) { } + + /** + * 查询结果解密游标,保持 MyBatis 游标的惰性读取语义。 + * + * @param 查询结果类型 + */ + private record DecryptCursor(Cursor delegate, EncryptedFieldProcessor encryptedFieldProcessor) + implements Cursor { + + @Override + public boolean isOpen() { + return delegate.isOpen(); + } + + @Override + public boolean isConsumed() { + return delegate.isConsumed(); + } + + @Override + public int getCurrentIndex() { + return delegate.getCurrentIndex(); + } + + @Override + public Iterator iterator() { + Iterator iterator = delegate.iterator(); + return new Iterator<>() { + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public T next() { + T result = iterator.next(); + encryptedFieldProcessor.decrypt(result); + return result; + } + }; + } + + @Override + public void close() throws IOException { + delegate.close(); + } + } } diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java index ae4c05be7..2516649b8 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java @@ -13,8 +13,7 @@ import java.util.Properties; /** * 入参加密拦截器 * - * @author 老马 - * @version 4.6.0 + * @author Lion Li */ @Intercepts({@Signature( type = ParameterHandler.class, @@ -26,6 +25,13 @@ public class MybatisEncryptInterceptor implements Interceptor { private final EncryptedFieldProcessor encryptedFieldProcessor; + /** + * 加密 MyBatis 入参中的加密字段,并在执行后恢复原始值。 + * + * @param invocation 拦截调用信息 + * @return MyBatis 执行结果 + * @throws Throwable 拦截处理异常 + */ @Override public Object intercept(Invocation invocation) throws Throwable { List snapshots = List.of(); @@ -45,11 +51,22 @@ public class MybatisEncryptInterceptor implements Interceptor { } } + /** + * 包装 MyBatis 目标对象。 + * + * @param target 目标对象 + * @return 包装后的对象 + */ @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } + /** + * 设置插件属性。 + * + * @param properties 插件属性 + */ @Override public void setProperties(Properties properties) { }