2009-07-03 2 views
7

Java ScriptEngine:Java側で値を使用していますか?私は、ユーザー定義のJavaScriptプログラムを起動していたJavaプログラムで

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

今、私は「結果」を使用したいと思います:どのように私はそれにアクセスすることができますか?それを配列として識別できますか?(メンバーを反復することはできますか)、StringIntegerなど...?

おかげ

EDITED: 私はちょうど私のユーザーは私の最後の値を返すスクリプトを与えたことを知っています。私はこの価値について何も知らない。それはString、配列などですか?私は知らないが、私はそれを使いたい。

答えて

0

このlinkが役に立ちます。あなたができるのは、実装固有のクラスに頼ることです。

9

おそらく単純な値を除いて、私はスクリプトエンジンがその値を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)); 
    } 

} 

スクリプトを編集することはできません場合でも、戻り値を取り、強制を行うには、独自の生成されたスクリプトを通してそれを渡すことができます。これは、返される値について何か知っていることを前提としています。


EDIT:何も戻り値については知られていないので、私が最初にそれがjava.langの種類の一つであったかどうかを確認するためのJava(getClass())を使用して、それをテストします。返されたオブジェクトがライブラリのプライベートなAPIから来た場合は、スクリプト言語(この場合はJavaScript)を使用してイントロスペクションします。おそらくJavaタイプに変換したり、そのプロパティをJavaデータ構造にプッシュしたりします。

JavaScriptは錆びていますが、John Leachのチュートリアルは非常によく見えます。JavaScript Introspection

(あなたはJavaのリフレクションを使用することができるかもしれないが、エンジンの実装は、Javaのバージョン/ JREが/ JavaScriptエンジンの間で変動する可能性があるので、私はそれに依存しないでしょう。)

2

この質問はとっくの昔に頼まれました、答えはまだ正しいように見えました。 JavaとJavascriptの間で複雑なオブジェクトを渡そうとしている他の人にとって興味がある場合は、私の解決策を提示したいと思います。

NativeObjectを(メモリ内の)JSONオブジェクトに変換するスクリプトを作成しました(実際には私はMongoDBのBSONベースのオブジェクトを使用しますが、下記のサンプルコードではJSONArrayとJSONObjectの代わりに1-1を使用できます)。

したがって、たとえば、関心のある「リターン」いくつかのオブジェクトや配列、私は(ユーザー)スクリプト「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" 

「create_object_script」スクリプトを制御できる場合は、これを1ステップで行うことができます。私のスクリプトはユーザによって生成されるので、この複雑さを隠すことが必要です。ユーザは、「戻り値」が最終行であるスクリプトを書くだけです。

この投稿の長さを維持するために、「parsing_script」hereを取得しました。

機能上、これは非常にうまく機能します。私はJSでそれほど多くを開発していないので、これを行うより効率的な方法がある可能性があります。 (私はあなたがBasicDBObject "outObj"を渡して、シングルトンの場合の代わりにそれを書くことができないなら、常にリストに結果を必要とします)。

昨日の午前1時に自分の状況で自分を見つけた人に役立ちます。

関連する問題