72 lines
2.5 KiB
Java
Raw Normal View History

2024-08-10 14:12:47 +08:00
package com.wflow.workflow.execute;
import cn.hutool.http.HttpRequest;
import com.wflow.exception.BusinessException;
import delight.nashornsandbox.NashornSandbox;
import delight.nashornsandbox.NashornSandboxes;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import lombok.extern.slf4j.Slf4j;
import javax.script.Invocable;
import javax.script.ScriptException;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
/**
* @author : willian fu
* @date : 2023/10/28
*/
@Slf4j
public class JsExecute {
//创建执行沙箱环境
private static NashornSandbox sandbox;
//TODO 这里配置允许暴露给的java类可以在js里面直接调用
private static final Class[] alowJsCallJavaClass = new Class[]{
HttpRequest.class, System.class
};
public JsExecute(ExecutorService executorService) {
if (Objects.isNull(sandbox)) {
sandbox = NashornSandboxes.create();
//沙箱资源限制
sandbox.setMaxCPUTime(20000);
sandbox.setMaxMemory(10 * 1024 * 1024);
sandbox.allowNoBraces(false);
sandbox.setMaxPreparedStatements(30);
sandbox.setExecutor(executorService);
sandbox.allowGlobalsObjects(true);
sandbox.allowPrintFunctions(true);
sandbox.disallowAllClasses();
//这里配置允许暴露的java类可以在js里面直接调用
for (Class clazz : alowJsCallJavaClass) {
sandbox.allow(clazz);
}
}
}
public <T> T execute(String func, String script, Class<T> resultType, Object... args) {
Invocable invocable = sandbox.getSandboxedInvocable();
try {
sandbox.eval(script);
Object result = invocable.invokeFunction(func, args);
log.debug("资源服务执行js解码结果[{}]", result);
if (result instanceof ScriptObjectMirror) {
//返回的是js对象 = Map<String, Object>
return ((ScriptObjectMirror) result).to(resultType);
} else {
//返回普通类型数据
return resultType.cast(result);
}
} catch (ScriptException | NoSuchMethodException e) {
log.error("js 函数[{}] [{}]执行异常: [{}]", func, script, e.getMessage());
throw new BusinessException("js函数解析执行异常:" + e.getMessage());
}
}
public void executeVoid(String func, String script, Object... args) {
execute(func, script, Object.class, args);
}
}