diff --git a/.drone.yml b/.drone.yml
index f1d8d41..3dec36a 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -74,7 +74,7 @@ volumes:
path: /home/build/fateverse
- name: skywalking
host:
- path: /home/skywalking-agent
+ path: /home/build/skywalking-agent
- name: config # k8s对接的配置文件
host:
path: /home/kubect
diff --git a/Dockerfile b/Dockerfile
index d28e349..172bad7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,17 +2,15 @@ FROM azul/zulu-openjdk:11.0.22-jdk
VOLUME /tmp
RUN useradd -b /home -m -s /bin/bash clay
RUN chmod a+xr -R /home/clay && chown clay:clay -R /home/clay
-#COPY skywalking /home/clay/skywalking-agent
-#RUN chmod a+xr -R /home/clay/skywalking-agent && chown clay:clay -R /home/clay/skywalking-agent
+COPY skywalking /home/clay/skywalking-agent
+RUN chmod a+xr -R /home/clay/skywalking-agent && chown clay:clay -R /home/clay/skywalking-agent
USER clay
ARG NAME=$DRONE_COMMIT_BRANCH
COPY ./$NAME.jar /home/clay/$NAME.jar
COPY start.sh /home/clay/start.sh
WORKDIR /home/clay
RUN mkdir -p /home/clay/logs && touch /home/clay/logs/spring.log
-#RUN mkdir -p /home/clay/code
-#RUN chmod 777 /home/clay/code
-#RUN mkdir -p /home/clay/skywalking-agent/logs && touch /home/clay/skywalking-agent/logs/skywalking-api.log
+RUN mkdir -p /home/clay/skywalking-agent/logs && touch /home/clay/skywalking-agent/logs/skywalking-api.log
ENV REF_NAME dev
EXPOSE 8080
CMD bash /home/clay/start.sh $REF_NAME && echo "start logging..." && : > /home/clay/logs/spring.log && tail -F -n 500 /home/clay/logs/spring.log
\ No newline at end of file
diff --git a/README.md b/README.md
index 446a9c8..a0024d1 100644
--- a/README.md
+++ b/README.md
@@ -21,12 +21,12 @@
| 依赖 | 版本 |
|----------------------|------------|
-| Spring Boot | 2.7.5 |
-| Spring Cloud | 2021.0.5 |
-| Spring Cloud Alibaba | 2021.0.4.0 |
+| Spring Boot | 2.7.3 |
+| Spring Cloud | 2021.0.3 |
+| Spring Cloud Alibaba | 2021.0.1.0 |
| Mybatis | 3.5.2 |
| Vue | 3.1.3 |
-| React | 3.1.3 |
+| React | 18.2.0 |
### 模块说明
diff --git a/common/common-code/pom.xml b/common/common-code/pom.xml
index 9dea91f..6daff0a 100644
--- a/common/common-code/pom.xml
+++ b/common/common-code/pom.xml
@@ -21,6 +21,16 @@
cn.fateverse
common-core
+
+ org.graalvm.js
+ js-scriptengine
+ 22.1.0
+
+
+ org.graalvm.js
+ js
+ 22.1.0
+
\ No newline at end of file
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/JavaCodeAutoConfiguration.java b/common/common-code/src/main/java/cn/fateverse/common/code/JavaCodeAutoConfiguration.java
index 993a65e..ceaa52f 100644
--- a/common/common-code/src/main/java/cn/fateverse/common/code/JavaCodeAutoConfiguration.java
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/JavaCodeAutoConfiguration.java
@@ -13,8 +13,8 @@ import org.springframework.context.annotation.Bean;
public class JavaCodeAutoConfiguration {
@Bean
- public JavaCodeEngine javaCodeEngine(JavaCodeProperties javaCodeProperties){
- return new JavaCodeEngine(javaCodeProperties);
+ public JavaCodeEngine javaCodeEngine(JavaCodeProperties javaCodeProperties) {
+ return new JavaCodeEngine(javaCodeProperties.getClassPath());
}
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/console/ConsoleCapture.java b/common/common-code/src/main/java/cn/fateverse/common/code/console/ConsoleCapture.java
new file mode 100644
index 0000000..c5e8fc7
--- /dev/null
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/console/ConsoleCapture.java
@@ -0,0 +1,51 @@
+package cn.fateverse.common.code.console;
+
+import cn.fateverse.common.code.model.EngineResult;
+import cn.fateverse.common.core.exception.CustomException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+/**
+ * 控制台输出捕获
+ *
+ * @author Clay
+ * @date 2024/4/22 17:08
+ */
+public class ConsoleCapture {
+
+
+ /**
+ * 捕获方法
+ *
+ * @param task 任務
+ * @return 返回结果
+ */
+ public static EngineResult capture(Task task) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream oldOut = System.out;
+ System.setOut(new PrintStream(baos));
+ Object result;
+ String capturedOutput;
+ try {
+ result = task.execute();
+ } catch (Exception e) {
+ if (e instanceof CustomException) {
+ throw (CustomException) e;
+ }
+ throw new RuntimeException(e);
+ } finally {
+ System.setOut(oldOut);
+ // 从捕获的字节数组输出流中获取打印的文本
+ capturedOutput = baos.toString();
+ }
+ return new EngineResult(result, capturedOutput);
+ }
+
+
+ public interface Task {
+ Object execute() throws Exception;
+ }
+
+
+}
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java
index 180e34e..abeff1c 100644
--- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java
@@ -1,19 +1,21 @@
package cn.fateverse.common.code.engine;
-import cn.fateverse.common.code.config.JavaCodeProperties;
+import cn.fateverse.common.code.console.ConsoleCapture;
import cn.fateverse.common.code.exception.SandboxClassNotFoundException;
import cn.fateverse.common.code.lock.SegmentLock;
+import cn.fateverse.common.code.model.EngineResult;
import cn.fateverse.common.code.sandbox.SandboxClassLoader;
import cn.fateverse.common.code.sandbox.SandboxSecurityManager;
+import cn.fateverse.common.core.exception.CustomException;
+import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.ObjectUtils;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
+import java.io.*;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
@@ -36,9 +38,7 @@ public class JavaCodeEngine {
private final URL url;
- private final URLClassLoader classLoader;
-
- private final Map> classCache = new ConcurrentHashMap<>();
+ private final Map classCache = new ConcurrentHashMap<>();
private final SandboxSecurityManager securityManager = new SandboxSecurityManager(classCache);
@@ -47,54 +47,31 @@ public class JavaCodeEngine {
private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- public JavaCodeEngine(JavaCodeProperties javaCodeProperties) {
+ public JavaCodeEngine(String classPath) {
try {
- CLASS_PATH = javaCodeProperties.getClassPath();
+ CLASS_PATH = classPath;
File file = new File(CLASS_PATH);
if (!file.exists()) {
file.mkdirs();
}
url = file.toURI().toURL();
- classLoader = new SandboxClassLoader(new URL[]{url});
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
- /**
- * 执行方法
- *
- * @param code 代码字符串
- * @param className 类名
- * @param methodName 方法名
- * @param paramClass 参数类型数组
- * @param args 参数数组
- * @param development 是否为开发环境 开发环境下会将生成的类在执行完成后删除,不是生产环境则会缓存提高运行效率
- * @return 执行结果
- */
- public T execute(String code, String className, String methodName, Class>[] paramClass, Object[] args, boolean development) {
- if (development) {
- return developmentExecute(code, className, methodName, paramClass, args);
- } else {
- return onlineExecute(code, className, methodName, paramClass, args);
- }
- }
-
-
/**
* 用于在开发环境中执行代码的私有方法。
*
* @param code 需要执行的代码字符串
* @param className 类名
* @param methodName 方法名
- * @param paramClass 参数类型数组
* @param args 参数数组
- * @param 接收泛型
* @return 执行结构
*/
@SneakyThrows
- private T developmentExecute(String code, String className, String methodName, Class>[] paramClass, Object[] args) {
+ public EngineResult mockExecute(String code, String className, String methodName, Object[] args) {
Class> loadClass = null;
try {
// 加锁,确保类只加载一次
@@ -104,12 +81,12 @@ public class JavaCodeEngine {
// 创建一个URLClassLoader,用于加载代码字符串
tempClassLoader = new URLClassLoader(new URL[]{url});
// 编译代码字符串为类
- Class> tempClass = compilerClass(className, code, tempClassLoader);
- // 将编译好的类放入缓存
- classCache.put(className, tempClass);
- return tempClass;
+ return compilerClass(className, code, tempClassLoader);
} catch (Exception e) {
e.printStackTrace();
+ if (e instanceof CustomException) {
+ throw (CustomException) e;
+ }
// 异常处理,并抛出自定义的SandboxClassNotFoundException异常
throw new SandboxClassNotFoundException(e.getMessage());
} finally {
@@ -119,14 +96,17 @@ public class JavaCodeEngine {
}
});
// 获取需要执行的方法
- Method method = loadClass.getMethod(methodName, paramClass);
+ Method method = getMethod(methodName, loadClass);
// 设置安全检查器
System.setSecurityManager(securityManager);
// 执行方法并返回结果
- return (T) method.invoke(null, args);
+ return ConsoleCapture.capture(() -> method.invoke(null, args));
+ } catch (CustomException e) {
+ EngineResult result = new EngineResult();
+ result.setSuccess(Boolean.FALSE);
+ result.setConsole(e.getMessage());
+ return result;
} finally {
- // 从缓存中移除编译好的类
- classCache.remove(className);
// 清空安全检查器
System.setSecurityManager(null);
if (loadClass != null) {
@@ -153,37 +133,53 @@ public class JavaCodeEngine {
* @param code 需要执行的代码字符串
* @param className 类名
* @param methodName 方法名
- * @param paramClass 参数类型数组
* @param args 参数数组
- * @param 接收泛型
* @return 执行结构
*/
- private T onlineExecute(String code, String className, String methodName, Class>[] paramClass, Object[] args) {
+ public Object execute(String code, String className, String methodName, Object[] args) {
try {
Class> loadClass = null;
- loadClass = classCache.get(className);
- if (loadClass == null) {
- loadClass = getLoadClass(code, className);
- Method method = loadClass.getMethod(methodName, paramClass);
- System.setSecurityManager(securityManager);
- return (T) method.invoke(null, args);
+ //从缓存中获取
+ CacheWrapper wrapper = classCache.get(className);
+ //缓存中不存在
+ if (wrapper == null) {
+ //加载
+ wrapper = getLoadClass(code, className);
}
+ //获取到类信息
+ loadClass = wrapper.getClazz();
+ //获取方法
+ Method method = getMethod(methodName, loadClass);
+ //开启安全模式
+ System.setSecurityManager(securityManager);
+ //执行方法
+ return method.invoke(null, args);
} catch (Exception e) {
+ remove(className);
e.printStackTrace();
} finally {
System.setSecurityManager(null);
- File javaFile = new File(CLASS_PATH + className + JAVA_SUFFIX);
- if (javaFile.exists()) {
- javaFile.delete();
- }
- File classFile = new File(CLASS_PATH + className + CLASS_SUFFIX);
- if (classFile.exists()) {
- classFile.delete();
- }
}
return null;
}
+ /**
+ * 获取到方法
+ *
+ * @param methodName 方法名称
+ * @param loadClass 类信息
+ * @return 方法对象
+ */
+ private Method getMethod(String methodName, Class> loadClass) {
+ Method method = null;
+ for (Method declaredMethod : loadClass.getDeclaredMethods()) {
+ if (declaredMethod.getName().equals(methodName)) {
+ method = declaredMethod;
+ }
+ }
+ return method;
+ }
+
/**
* 获取到编译完成的Class对象
*
@@ -191,15 +187,18 @@ public class JavaCodeEngine {
* @param className 类名
* @return 编译后的Java对象
*/
- private Class> getLoadClass(String code, String className) {
+ private CacheWrapper getLoadClass(String code, String className) {
//使用分段锁,提高效率,放多并发情况下多次对同一个类进行编译
return SegmentLock.lock(className, () -> {
try {
+ URLClassLoader classLoader = new SandboxClassLoader(new URL[]{url});
//执行编译
Class> tempClass = compilerClass(className, code, classLoader);
+ //创建缓存包装对象
+ CacheWrapper wrapper = new CacheWrapper(tempClass, classLoader);
//将编译之后的类对象放在缓存中,提高线上环境的运行效率
- classCache.put(className, tempClass);
- return tempClass;
+ classCache.put(className, wrapper);
+ return wrapper;
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -215,32 +214,49 @@ public class JavaCodeEngine {
* @return 编译完成的类对象
*/
private Class> compilerClass(String className, String code, URLClassLoader classLoader) {
- log.info(code);
File tempFile = new File(CLASS_PATH + className + JAVA_SUFFIX);
try (FileWriter writer = new FileWriter(tempFile)) {
writer.write(code);
writer.close();
+ ByteArrayOutputStream errorStream = new ByteArrayOutputStream(10240);
// 编译.java文件
- compiler.run(null, null, null, tempFile.getPath());
+ compiler.run(null, null, errorStream, tempFile.getPath());
+ String trace = errorStream.toString();//存放控制台输出的字符串
+ if (!ObjectUtils.isEmpty(trace)) {
+ trace = trace.replace(CLASS_PATH + className + ".", "");
+ throw new CustomException("编译错误: " + trace);
+ }
return classLoader.loadClass(className);
} catch (Exception e) {
e.printStackTrace();
- throw new RuntimeException(e);
+ if (e instanceof CustomException) {
+ throw (CustomException) e;
+ }
+ throw new CustomException("执行或者编辑错误!");
}
}
/**
* 删除类
+ *
* @param className 删除类
* @return 删除结果
*/
public Boolean remove(String className) {
return SegmentLock.lock(className, () -> {
- classCache.remove(className);
+ CacheWrapper wrapper = classCache.get(className);
+ if (wrapper != null) {
+ classCache.remove(className);
+ wrapper.remove();
+ }
+ //进行gc 垃圾挥手
+ System.gc();
+ //删除Java文件
File javaFile = new File(CLASS_PATH + className + JAVA_SUFFIX);
if (javaFile.exists()) {
javaFile.delete();
}
+ //删除class文件
File classFile = new File(CLASS_PATH + className + CLASS_SUFFIX);
if (classFile.exists()) {
classFile.delete();
@@ -248,4 +264,24 @@ public class JavaCodeEngine {
return true;
});
}
+
+
+ @Getter
+ public static class CacheWrapper {
+
+ private Class> clazz;
+
+ private URLClassLoader classLoader;
+
+ public CacheWrapper(Class> clazz, URLClassLoader classLoader) {
+ this.clazz = clazz;
+ this.classLoader = classLoader;
+ }
+
+
+ public void remove(){
+ clazz = null;
+ classLoader = null;
+ }
+ }
}
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java
index 085390d..dd0542b 100644
--- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java
@@ -1,9 +1,15 @@
package cn.fateverse.common.code.engine;
-import javax.script.Invocable;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
+import cn.fateverse.common.code.console.ConsoleCapture;
+import cn.fateverse.common.code.lock.SegmentLock;
+import cn.fateverse.common.code.model.EngineResult;
+import cn.fateverse.common.core.exception.CustomException;
+import com.alibaba.fastjson2.JSON;
+import org.graalvm.polyglot.Context;
+import org.graalvm.polyglot.Value;
+
+import java.util.HashMap;
+import java.util.Map;
/**
* js 工具类
@@ -13,25 +19,89 @@ import javax.script.ScriptException;
*/
public class JavaScriptEngine {
+
+ // 创建 GraalVM 上下文
+ private static final Context context = Context.newBuilder()
+ .allowAllAccess(true)
+// .allowHostClassLoading(true)
+// .allowIO(true)
+// .allowNativeAccess(true)
+ .build();
+
+
+ private static final Map functionMap = new HashMap<>();
+
+
/**
* 执行js代码
- * @param script js脚本
- * @param function js函数名
- * @param args 参数
+ *
+ * @param script js脚本
+ * @param functionName js函数名
+ * @param args 参数
* @return 返回结构
- * @param 泛型类型
*/
- public static T executeScript(String script, String function, Object... args) {
- ScriptEngineManager manager = new ScriptEngineManager();
- ScriptEngine engine = manager.getEngineByName("JavaScript");
+ public static Object execute(String script, String functionName, Object args) {
try {
- engine.eval(script);
- Invocable inv = (Invocable) engine;
- return (T) inv.invokeFunction(function, args);
- } catch (ScriptException | NoSuchMethodException e) {
- throw new RuntimeException(e);
+ Value executeFunction = getFunction(functionName, script);
+ Value javaObjectAsValue = Value.asValue(args);
+ Value result = executeFunction.execute(javaObjectAsValue);
+ return result.as(Object.class);
+ } catch (Exception e) {
+ remove(functionName);
+ throw new CustomException("运行失败!");
}
}
+ public static EngineResult mockExecute(String script, String functionName, Object args) {
+ try {
+ return ConsoleCapture.capture(() -> {
+ Context context = Context.newBuilder()
+ .allowAllAccess(true)
+// .allowHostClassLoading(true)
+// .allowIO(true)
+// .allowNativeAccess(true)
+ .build();
+ try {
+ context.eval("js", script);
+ } catch (Exception e) {
+ String message = e.getMessage();
+ message = message.replace("java.lang.RuntimeException: org.graalvm.polyglot.PolyglotException: SyntaxError:", "");
+ throw new CustomException("js has error : " + message);
+ }
+ Value executeFunction = context.getBindings("js").getMember(functionName);
+ Value javaObjectAsValue = Value.asValue(args);
+ Value result = executeFunction.execute(javaObjectAsValue);
+ return result.as(Object.class);
+ });
+ } catch (CustomException e) {
+ EngineResult result = new EngineResult();
+ result.setSuccess(Boolean.FALSE);
+ result.setConsole(e.getMessage());
+ return result;
+ }
+ }
+
+
+ private static Value getFunction(String functionName, String script) {
+ return SegmentLock.lock(functionName, () -> {
+ if (functionMap.containsKey(functionName)) {
+ return functionMap.get(functionName);
+ }
+ context.eval("js", script);
+ Value executeFunction = context.getBindings("js").getMember(functionName);
+ functionMap.put(functionName, executeFunction);
+ return executeFunction;
+ });
+ }
+
+
+ public static void remove(String functionName) {
+ SegmentLock.lock(functionName, () -> {
+ functionMap.remove(functionName);
+ return null;
+ });
+ }
+
+
}
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/lock/SegmentLock.java b/common/common-code/src/main/java/cn/fateverse/common/code/lock/SegmentLock.java
index 48933de..c21c459 100644
--- a/common/common-code/src/main/java/cn/fateverse/common/code/lock/SegmentLock.java
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/lock/SegmentLock.java
@@ -6,6 +6,8 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
/**
+ * 分段锁对象
+ *
* @author Clay
* @date 2023-10-25
*/
@@ -15,10 +17,11 @@ public class SegmentLock {
/**
* 分段锁
- * @param key 锁名称
+ *
+ * @param key 锁名称
* @param supplier 需要执行的函数
+ * @param 接收泛型
* @return 执行后的结果
- * @param 接收泛型
*/
public static T lock(String key, Supplier supplier) {
ReentrantLock lock = lockMap.get(key);
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java b/common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java
new file mode 100644
index 0000000..2f6b8a1
--- /dev/null
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java
@@ -0,0 +1,28 @@
+package cn.fateverse.common.code.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Clay
+ * @date 2024/4/22 17:10
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class EngineResult {
+
+ private Object result;
+
+
+ private String console;
+
+ private Boolean success;
+
+ public EngineResult(Object result, String console) {
+ success = true;
+ this.result = result;
+ this.console = console;
+ }
+}
diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/sandbox/SandboxSecurityManager.java b/common/common-code/src/main/java/cn/fateverse/common/code/sandbox/SandboxSecurityManager.java
index 72c1d12..894bfc2 100644
--- a/common/common-code/src/main/java/cn/fateverse/common/code/sandbox/SandboxSecurityManager.java
+++ b/common/common-code/src/main/java/cn/fateverse/common/code/sandbox/SandboxSecurityManager.java
@@ -1,5 +1,7 @@
package cn.fateverse.common.code.sandbox;
+import cn.fateverse.common.code.engine.JavaCodeEngine;
+
import java.io.FilePermission;
import java.lang.reflect.ReflectPermission;
import java.security.Permission;
@@ -9,9 +11,9 @@ import java.util.Set;
public class SandboxSecurityManager extends SecurityManager {
- private final Map> classCache;
+ private final Map classCache;
- public SandboxSecurityManager(Map> classCache) {
+ public SandboxSecurityManager(Map classCache) {
this.classCache = classCache;
}
@@ -38,7 +40,7 @@ public class SandboxSecurityManager extends SecurityManager {
private boolean isAllowedPermission(Permission permission) {
//权限:用于校验文件系统访问权限,包括读取、写入、删除文件,以及目录操作。权限名称可能包括文件路径和操作,如 "read", "write", "delete", "execute" 等。
- if (permission instanceof FilePermission){
+ if (permission instanceof FilePermission) {
System.out.println("触发文件读写权限");
return false;
}
diff --git a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java
index a378b65..9f2daf5 100644
--- a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java
+++ b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java
@@ -12,4 +12,23 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt {
+
+ Position value() default Position.ALL;
+
+
+ EncryptType type() default EncryptType.SM4;
+
+
+ enum EncryptType {
+
+ SM4,
+
+ }
+
+ enum Position {
+ ALL,
+ OUT,
+ IN
+ }
+
}
diff --git a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java
index d3d5582..f361306 100644
--- a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java
+++ b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java
@@ -11,4 +11,12 @@ import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptField {
+
+ Position value() default Position.ALL;
+
+ enum Position {
+ ALL,
+ OUT,
+ IN
+ }
}
\ No newline at end of file
diff --git a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java
index e72f998..73152dc 100644
--- a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java
+++ b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java
@@ -2,6 +2,7 @@ package cn.fateverse.common.decrypt.aspect;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.core.result.Result;
+import cn.fateverse.common.decrypt.annotation.Encrypt;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import cn.fateverse.common.decrypt.service.EncryptService;
import lombok.extern.slf4j.Slf4j;
@@ -11,12 +12,10 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.ReflectionUtils;
-import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
@Slf4j
@Aspect
@@ -41,36 +40,35 @@ public class EncryptAspect {
@Around("@annotation(cn.fateverse.common.decrypt.annotation.Encrypt)")
public Object decryptField(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
- //获取请求参数
- Object[] args = point.getArgs();
//获取方法
Method method = signature.getMethod();
- //获取方法参数 Parameter对象集 参数修饰符、参数名、注解及注解类型
- Parameter[] parameters = method.getParameters();
- for (int i = 0; i < parameters.length; i++) {
- Parameter parameter = parameters[i];
- //获取参数注解
- EncryptField encryptField = parameter.getAnnotation(EncryptField.class);
- Object arg = args[i];
- if (null != encryptField) {
- if (arg instanceof String) {
- String decrypt = encryptService.decrypt((String) arg);
- args[i] = decrypt;
- } else if (arg instanceof List) {
- try {
- List list = (List) arg;
- list.replaceAll(encryptService::decrypt);
- args[i] = list;
- } catch (Exception e) {
- throw new CustomException("接受参数类型错误,请使用String类型的泛型参数");
- }
- }
- } else if (parameter.getType().getName().startsWith(BASE_PACKAGE)) { //返回一个类对象,该类对象标识此参数对象表示的参数的声明类型
- decrypt(arg);
- }
+ Encrypt encrypt = method.getAnnotation(Encrypt.class);
+ if (encrypt == null) {
+ return point.proceed();
+ }
+ //获取请求参数
+ Object[] args = point.getArgs();
+ if (Encrypt.Position.ALL.equals(encrypt.value()) || Encrypt.Position.IN.equals(encrypt.value())) {
+ decryptParams(args, method);
}
//正常执行业务,最后返回的返回值为Result
Object proceed = point.proceed(args);
+ if (Encrypt.Position.ALL.equals(encrypt.value()) || Encrypt.Position.OUT.equals(encrypt.value())) {
+ Result