7

这可能不切实际,但我将其作为一项任务。我在java中有一个打开的ServerSocket。现在我想读取一个包含 html 和 javascript 的文件,并将 javascript 结果输出到浏览器。所以这样,我将在服务器端评估 javascript。所以我想要评估里面的东西。

我试过这个来测试,它工作但它有一些问题,例如它将消息打印到 System.out。和 engine.eval("print('Welocme to java worldddd')"); 不返回字符串,以便我可以将其输出到套接字的输出流:

import javax.script.*;
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
     // evaluate JavaScript code from String
     engine.eval("print('Welocme to java worldddd')");
     //engine.eval("a");
} catch (ScriptException ex) {
     Logger.getLogger(doComms.class.getName()).log(Level.SEVERE, null, ex);
}
4

4 回答 4

11

您可以print()通过将 writer 设置为ScriptContext

ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
ScriptContext context = engine.getContext();
StringWriter writer = new StringWriter();
context.setWriter(writer);

engine.eval("print('Welocme to java worldddd')");

String output = writer.toString();

System.out.println("Script output: " + output);
于 2013-04-03T12:55:01.950 回答
7

我过去通过在内部创建一个 javascript 函数eval()并调用它来获得结果来解决这个问题:

import javax.script.*;
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
     // evaluate JavaScript code from String
     engine.eval("function sum(a,b){ return a + b;}");
     System.out.println(((Invocable) engine).invokeFunction("sum", new Object[]{10,20}));
} catch (ScriptException ex) {
     Logger.getLogger(doComms.class.getName()).log(Level.SEVERE, null, ex);
}

请注意,invokeFunction(第一个参数)中的函数名称应与之前声明的名称匹配。

请记住,这可能很危险。您对 javascript 代码的来源有绝对的控制权吗?否则,一个简单while(true){}的对您的服务器来说可能是灾难性的。

于 2013-04-03T13:01:04.150 回答
0
public static String convertEnumToJson(Class<? extends Enum<?>> cls) throws ScriptException, NoSuchMethodException, IllegalAccessException {
    List<Map<String, Object>> map = createMap(Colors.class);
    return createJson(map);
}

public static List<Map<String, Object>> createMap(Class<? extends Enum<?>> cls) throws IllegalAccessException {
    List<Map<String, Object>> res = new ArrayList<>();

    for (Enum<?> item : cls.getEnumConstants()) {
        Map<String, Object> map = new LinkedHashMap<>();

        for (Field field : item.getClass().getDeclaredFields()) {
            if (field.getType() != item.getClass() && !"$VALUES".equals(field.getName())) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(item));
            }
        }

        res.add(map);
    }

    return res;
}

// It's better to use Jackson or similar lib for read/write json
public static <T> String createJson(T obj) throws ScriptException, NoSuchMethodException {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("JavaScript");
    engine.eval("function sum(a){ return a;}");
    return ((Invocable)engine).invokeFunction("sum", obj).toString();
}
于 2019-05-31T11:22:25.257 回答
0

如果最近有人像我一样偶然发现了这个页面,请注意 Nashorn 已被弃用。

您可以探索其他可用的替代方案。

于 2021-04-19T05:35:02.410 回答