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 execute(String func, String script, Class 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 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); } }