热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScriptEngine:在Java端使用值?-JavaScriptEngine:usingvalueonJavaside?

InaJavaprogramIminvokingauser-definedJavaScriptprogram:在Java程序中,我正在调用用户定义的JavaScript程序:

In a Java program I'm invoking a user-defined Javascript program:

在Java程序中,我正在调用用户定义的Javascript程序:

File userJSFile=...;
javax.script.ScriptEngineManager mgr=new  ScriptEngineManager();
javax.script.ScriptEngine scripEngine= mgr.getEngineByExtension("js");
Object result=scripEngine.eval(new java.io.FileReader(userJSFile));

Now I would like to use 'result': how can I have an access to it? Can I identify it as an array (Can I iterate threw its members), a String, an Integer, etc... ?

现在我想使用'结果':我怎样才能访问它?我可以将它识别为一个数组(我可以迭代它的成员),一个字符串,一个整数等......?

Thanks

EDITED: I just know that my user gave me a script returning the last value. I don't know anything about this value. Is it a String, an array, etc.. ? I don't known but I want to use it.

编辑:我只知道我的用户给了我一个脚本返回最后一个值。我对这个价值一无所知。它是一个字符串,一个数组等..?我不知道,但我想用它。

3 个解决方案

#1


Except perhaps for simple values, I would rather let the scripting engine coerce its values to Java types.

除了简单的值之外,我宁愿让脚本引擎将其值强制转换为Java类型。

public class ScriptDemo {

  static class Result {
    private String[] words;

    public void setWords(String[] words) {
      this.words = words;
    }
  }

  static final String SCRIPT = "var foo = 'Hello World!';\n"
      + "result.setWords(foo.split(' '));";

  public static void main(String[] args)
      throws ScriptException {
    Result result = new Result();
    javax.script.ScriptEngineManager mgr = new ScriptEngineManager();
    javax.script.ScriptEngine scripEngine = mgr
        .getEngineByExtension("js");
    scripEngine.getContext().setAttribute("result", result,
        ScriptContext.ENGINE_SCOPE);
    scripEngine.eval(SCRIPT);
    System.out.println(Arrays.toString(result.words));
  }

}

Even if you can't edit the script, you could take the return value and pass it through your own generated script to do the coercion. This assumes you know something about the value being returned.

即使您无法编辑脚本,也可以获取返回值并将其传递给您自己生成的脚本以执行强制操作。这假设您了解返回的值。


EDIT: since nothing is known about the return value, I would first test it using Java (getClass()) to see if it was one of the java.lang types. If the returned object is from some API private to the library, I would introspect it using the scripting language (in this case Javascript), possibly coercing it to a Java type or pushing its properties into some Java data structure during the process.

编辑:因为对返回值一无所知,我首先使用Java(getClass())测试它是否是java.lang类型之一。如果返回的对象来自某些私有API,那么我会使用脚本语言(在本例中为Javascript)对其进行内省,可能会将其强制转换为Java类型,或者在此过程中将其属性推送到某些Java数据结构中。

My Javascript is rusty, but John Leach's tutorial looks quite good: Javascript Introspection.

我的Javascript很生疏,但John Leach的教程看起来很不错:Javascript内省。

(You may be able to use Java reflection, but since the engine implementation could vary between Java versions/JREs/Javascript engines, I wouldn't rely on it.)

(您可能可以使用Java反射,但由于Java版本/ JRE / Javascript引擎之间的引擎实现可能不同,我不会依赖它。)

#2


This question was asked ages ago, but the answers still seemed correct. In case it's of interest to anyone else trying to pass complex objects between Java and Javascript, I wanted to present my solution.

很久以前就提出过这个问题,但答案似乎仍然正确。如果其他人试图在Java和Javascript之间传递复杂对象感兴趣,我想提出我的解决方案。

I wrote a script that converts the NativeObject to (in-memory) JSON objects (actually I use MongoDB's BSON-based objects, but you should just be able to substitute 1-1 for JSONArray and JSONObject in the sample code below).

我编写了一个脚本,将NativeObject转换为(内存中)JSON对象(实际上我使用MongoDB的基于BSON的对象,但您应该只能在下面的示例代码中用1-1代替JSONArray和JSONObject)。

So for example, say I have a (user) script "create_object_script", which "returns" some object or array of interest, then I can convert it into JSON (ie a list of hashmaps) as follows:

例如,假设我有一个(用户)脚本“create_object_script”,它“返回”一些感兴趣的对象或数组,然后我可以将其转换为JSON(即一个哈希映射列表),如下所示:

Object returnVal = engine.eval(create_object_script);
engine.put("output", returnVal);
BasicDBObject objFactory = new BasicDBObject(); // (or JSON equivalent)
BasicDBList listFactory = new BasicDBList(); // (or JSON equivalent)
BasicDBList outList = new BasicDBList(); // (or JSON equivalent)
engine.put("objFactory", objFactory);
engine.put("listFactory", listFactory);
engine.put("outList", outList);
engine.eval(parsing_script); // (described below)
// "outList" is now populated with (in-memory) JSON representations of "returnVal"

Obviously if you have control over the "create_object_script" script you can do this in a single step; my scripts are user-generated so hiding away this complexity is necessary - the users just write scripts where the "return value" is the final line.

显然,如果您可以控制“create_object_script”脚本,则只需一步即可完成;我的脚本是用户生成的,因此隐藏这种复杂性是必要的 - 用户只需编写脚本,其中“返回值”是最后一行。

I gisted the "parsing_script" here to keep the length of this post down.

我在这里引用了“parsing_script”来保持这篇文章的篇幅。

Functionally this works very nicely; I haven't developed in JS much so it's possible there are more efficient ways of doing this. (Note I always need my results in a list, if you don't then you could pass in a BasicDBObject "outObj" and write to that instead in the singleton case).

功能上这非常好用;我没有在JS中开发过多,所以有可能有更有效的方法来实现这一点。 (注意我总是需要我在列表中的结果,如果你不这样做,那么你可以传入一个BasicDBObject“outObj”并在单例情况下写入它)。

Hope this helps someone who finds themselves in my situation at 1am last night!

希望这可以帮助那些在昨晚凌晨1点发现自己的人!

#3


This link may be helpful. It seems that the best you can do is to rely on an implementation specific class.

此链接可能会有所帮助。看来,您可以做的最好的事情就是依赖于特定于实现的类。


推荐阅读
author-avatar
mobiledu2502881483
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有