问题描述
我正在努力在 Spring Boot 中开发一个 REST API,它将接受请求正文中的任何 groovy 脚本,并将在服务器上执行它并返回执行的结果。我试图找出如何获取脚本的执行结果,即使脚本明确没有返回任何值。这就像一个在线 groovy 编译器,您可以在其中发布代码并获得结果
import groovy.lang.GroovyClassLoader;
import groovy.lang.groovyshell;
import groovy.lang.Script;
public class GroovyController {
public static void main(String[] args) throws ScriptException {
System.out.println(runScript());
}
public static String runScript(){
String script = "class Student {\n" +
" private int StudentID;\n" +
" private String StudentName;\n" +
"\t\n" +
" void setStudentID(int pID) {\n" +
" StudentID = pID;\n" +
" }\n" +
"\t\n" +
" void setStudentName(String pName) {\n" +
" StudentName = pName;\n" +
" }\n" +
"\t\n" +
" int getStudentID() {\n" +
" return this.StudentID;\n" +
" }\n" +
"\t\n" +
" String getStudentName() {\n" +
" return this.StudentName;\n" +
" }\n" +
"\t\n" +
" static void main(String[] args) {\n" +
" Student st = new Student();\n" +
" st.setStudentID(1);\n" +
" st.setStudentName(\"Joe\");\n" +
"\t\t\n" +
" println(st.getStudentID());\n" +
" println(st.getStudentName());\n" +
" } \n" +
"}";
groovyshell shell = new groovyshell();
Object result = shell.evaluate(script);
return result.toString();
}
}
解决方法
我已经弄清楚如何在安全沙箱模型中使用 java 运行 groovy 脚本。我使用 run 类的 Groovy Shell 方法用 java 运行 groovy 脚本。如果执行的脚本本身返回任何值,如 return 2 * 4
将返回 4,如果脚本没有任何 return 语句并且 shell 的 run 方法将返回 null,则 Run 方法返回结果。
在 println("Hello world!!")
的情况下,它不会明显返回任何内容,但是在 API 的请求负载中发送此脚本的客户端会期望打印文本作为响应。为了捕获 PrintStream 写入的内容,可以使用 binding 将自定义 PrintWriter 绑定到 GroovyShell 中的 out 对象。我编写了一个完整的基于 Spring Boot 的微服务,它公开了一个 REST API 以在安全的沙箱模型中在服务器上执行 Groovy 脚本。
可以在此处找到完整的微服务代码 Script Execution Service