2009-07-03 26 views
7

Bir Java programında kullanıcı tanımlı bir JavaScript programı başlatıyorum:Java ScriptEngine: Java tarafında değer mi kullanıyorsunuz?

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

Şimdi ' sonucu' kullanmak istiyorum: ona nasıl erişebilirim? Bunu bir dizi olarak tanımlayabilir miyim (Ben üyelerini attırabilir miyim), bir String, Integer, vs ...?

Teşekkürler

EDİLDİ: Kullanıcıların bana son değeri döndüren bir script verdiğini biliyorum. Bu değer hakkında hiçbir şey bilmiyorum. Bu bir String, bir dizi mi, ..? Bilmiyorum ama kullanmak istiyorum.

cevap

0

Bu link yardımcı olabilir. Yapabileceğin en iyi şey, uygulamaya özel bir sınıfa güvenmek.

9

Belki de basit değerler için, komut dosyası altyapısının değerlerini Java türlerine zorlamasına izin vermekteyim.

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)); 
    } 

} 

komut dosyasını düzenleyemezsiniz bile, dönüş değeri alıp zorlama yapmak için kendi oluşturulan komut dosyası aracılığıyla bunu geçebileceği. Bu, döndürülen değer hakkında bir şey bildiğini varsayar.


DÜZENLEME: hiçbir şey dönüş değeri hakkında bilinen beri ilk o java.lang türlerinden biri olup olmadığını görmek için (getClass()) Java kullanarak test ediyorum. Döndürülmüş nesne kütüphane için özel bir API'den geliyorsa, komut dosyası dilini (bu durumda JavaScript) kullanarak, muhtemelen bir Java türüne zorlayarak veya özelliklerini işlem sırasında bazı Java veri yapısına zorlayarak değerlendiririm.

JavaScript'im paslı ama John Leach'ın öğreticisi oldukça iyi görünüyor: JavaScript Introspection.

(Java yansıması kullanmak mümkün olabilir, ama motor uygulama Java sürümleri/JRE/JavaScript motorları arasında değişebilir ondan ben güvenmek olmaz.)

2

Bu soru sorulmuştur çağlar önce, ama cevaplar hala doğru görünüyordu. Java ve Javascript arasındaki karmaşık nesneleri geçmeye çalışanların ilgisini çekiyorsa, çözümümüzü sunmak istedim.

NativeObject to (bellek içi) JSON nesnelerini dönüştüren bir betik yazdım (aslında MongoDB'nin BSON tabanlı nesnelerini kullanıyorum, ancak aşağıdaki örnek kodda yalnızca JSONArray ve JSONObject yerine 1-1 yazabilmelisiniz)). Yani, örneğin

, şöyle bazı nesne veya ilgi dizisi, o zaman ben JSON içine (hashmaps yani bir liste) dönüştürebilirsiniz "döner" a (kullanıcı) komut "create_object_script" var ki:

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" 

Açıkça "create_object_script" komut dosyası üzerinde denetiminiz varsa bunu tek adımda yapabilirsiniz; benim betiklerim kullanıcı tarafından oluşturulmuş, bu yüzden bu karmaşıklığı saklamak gereklidir - kullanıcılar sadece "geri dönüş değeri" nin son satır olduğu komut dosyaları yazarlar.

Bu gönderinin uzunluğunu korumak için "parsing_script" here'u veriyorum.

Fonksiyonel olarak bu çok güzel çalışır; JS'de geliştirmedim, bu yüzden bunu yapmanın daha verimli yolları var. (Not: Her zaman sonuçlarımda bir listeye ihtiyacım var, eğer yapmıyorsanız, o zaman bir BasicDBObject "outObj" yazabilir ve bunun yerine singleton durumunda yazabilirsiniz).

Bu, dün gece saat 1'de durumumda kendini bulan birini işe yarar.