2009-07-03 6 views
7

Trong một chương trình Java Tôi gọi một người dùng xác định chương trình JavaScript:Java ScriptEngine: sử dụng giá trị ở phía 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)); 

Bây giờ tôi muốn sử dụng 'kết quả': làm thế nào tôi có thể có quyền truy cập vào nó? Tôi có thể xác định nó như là một mảng (Tôi có thể lặp lại ném các thành viên của nó), một String, một Integer, v.v ...?

Cảm ơn

EDITED: Tôi chỉ biết rằng người dùng của tôi đã cho tôi một kịch bản trả lại giá trị cuối cùng. Tôi không biết gì về giá trị này. Đây có phải là String, một mảng, v.v. không? Tôi không biết nhưng tôi muốn sử dụng nó.

Trả lời

0

Điều này link có thể hữu ích. Dường như tốt nhất bạn có thể làm là dựa vào một lớp cụ thể thực hiện.

9

Ngoại trừ có lẽ đối với các giá trị đơn giản, tôi thà để cho công cụ tạo script kết hợp các giá trị của nó với các loại 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)); 
    } 

} 

Thậm chí nếu bạn không thể chỉnh sửa tập lệnh, bạn có thể lấy giá trị trả lại và chuyển nó qua tập lệnh được tạo của riêng bạn để thực hiện cưỡng chế. Điều này giả định bạn biết điều gì đó về giá trị được trả về.


EDIT: vì không có gì được biết về giá trị trả về, đầu tiên tôi sẽ kiểm tra nó sử dụng Java (getClass()) để xem nếu nó là một trong những loại java.lang. Nếu đối tượng trả về là từ một số API riêng tư cho thư viện, tôi sẽ xem xét nó bằng cách sử dụng ngôn ngữ kịch bản (trong trường hợp này là JavaScript), có thể ép nó vào một kiểu Java hoặc đẩy các thuộc tính của nó vào một số cấu trúc dữ liệu Java trong suốt quá trình.

JavaScript của tôi bị gỉ, nhưng hướng dẫn của John Leach có vẻ khá tốt: JavaScript Introspection.

(Bạn có thể sử dụng Java phản chiếu, nhưng kể từ khi thực hiện động cơ có thể thay đổi giữa các phiên bản/JRE/động cơ Java Javascript, tôi sẽ không dựa vào nó.)

2

lứa tuổi Câu hỏi này đã được hỏi trước, nhưng câu trả lời vẫn có vẻ đúng. Trong trường hợp nó quan tâm đến bất cứ ai khác cố gắng để vượt qua các đối tượng phức tạp giữa Java và Javascript, tôi muốn trình bày giải pháp của tôi.

Tôi đã viết một tập lệnh chuyển đổi các đối tượng JSON NativeObject (trong bộ nhớ) (thực ra tôi sử dụng các đối tượng dựa trên BSON của MongoDB, nhưng bạn chỉ có thể thay thế 1-1 cho JSONArray và JSONObject trong mã mẫu bên dưới). Ví dụ: giả sử tôi có một tập lệnh (người dùng) "create_object_script", mà "trả về" một số đối tượng hoặc mảng quan tâm, sau đó tôi có thể chuyển đổi nó thành JSON (ví dụ: danh sách các hashmaps) như sau:

&hl=vi
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" 

Rõ ràng nếu bạn có quyền kiểm soát tập lệnh "create_object_script", bạn có thể thực hiện việc này trong một bước; kịch bản của tôi được người dùng tạo ra để ẩn đi sự phức tạp này là cần thiết - người dùng chỉ cần viết tập lệnh trong đó "giá trị trả về" là dòng cuối cùng.

Tôi gisted "parsing_script" here để duy trì độ dài của bài đăng này.

Chức năng này hoạt động rất độc đáo; Tôi đã không phát triển trong JS nhiều vì vậy nó có thể có những cách hiệu quả hơn để làm điều này. (Lưu ý tôi luôn luôn cần kết quả của tôi trong một danh sách, nếu bạn không thì bạn có thể vượt qua trong một BasicDBObject "outObj" và ghi vào đó thay vì trong trường hợp singleton).

Hy vọng điều này sẽ giúp ai đó tìm thấy chính mình trong tình huống của tôi lúc 1 giờ tối qua!