【发布时间】:2017-06-15 12:59:25
【问题描述】:
我想将名为“entities”的全局属性放在 JS 范围内。 Entity 基本上是描述 Person 的 Java 类。
public class EntityJS extends ScriptableObject {
private String firstName;
private String lastName;
private Double salary;
private String email;
@Override
public String getClassName() {
return "Entity";
}
public EntityJS() {
}
public EntityJS(String firstName, String lastName, Double salary, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.salary = salary;
this.email = email;
}
public void jsConstructor() {
this.firstName = "";
this.lastName = "";
this.salary = 0.;
this.email = "";
}
public void jsSet_salary(Double value) {
this.salary = value;
}
public Double jsGet_salary() {
return this.salary;
}
public void jsSet_firstName(String value) {
this.firstName = value;
}
//the rest of getters & setters
}
Entity 类与 EntityJS 几乎相同,只是它仅扩展了 java Object。
我想允许 javascript 用户修改全局变量“entities”。执行用户脚本后,我想将此对象检索回 Java(并稍后执行一些操作)。
我用结果和预期的返回值评论了有趣的行。 这是我尝试执行用户代码的代码:
public String execute(String code, ObservableList<Entity> entities) {
Context context = Context.enter();
try {
Scriptable scope = context.initStandardObjects();
ScriptableObject.defineClass(scope, EntityJS.class, true, true);
EntityJS[] objects = new EntityJS[entities.size()];
for(int i = 0; i < entities.size(); ++i){
objects[i] = new EntityJS(entities.get(i).getFirstName(), entities.get(i).getLastName(), entities.get(i).getSalary(), entities.get(i).getEmail());
}
ScriptableObject.putProperty(scope, "e1", Context.javaToJS(objects, scope));
// typing "e1" (which is equal to "code" value) returns "[Lentity.EntityJS;@7959b389"
Object[] array = entities.toArray();
ScriptableObject.putProperty(scope, "e2", array);
// same for e1
Object wrappedOut = Context.javaToJS(entities, scope);
ScriptableObject.putProperty(scope, "e3", wrappedOut);
//this works quite nice, but it doesn't behave like JS object
//it returns, good-looking array:
//[Entity{firstName='Alwafaa', lastName='Abacki', salary=1000.0, email='zdzisiek@adad.com'},
//Entity{firstName='chero', lastName='Cabacki', salary=2000.0, email='bfadaw@dadaad.com'}]
//Unfortunately, if I want to get e.g. salary value I have to call
//e.get(0).getSalary() which returns string :(
//if I want to add number I have to call
//Number(e.get(0).getSalary()) to get Number
ScriptableObject.putProperty(scope, "e4", Context.javaToJS(objects[0], scope));
//this results in "TypeError: Cannot find default value for object."
Object result = context.evaluateString(scope, code, "<cmd>", 1, null);
return context.toString(result);
} catch (Exception ex) {
System.out.println(ex.getMessage());
return ex.getMessage();
} finally {
Context.exit();
}
}
我想给用户“实体”类似 JS 的数组,它可以被修改,例如这样:
entities.forEach(function(entity){entity.salary += 1000;})
当然,我希望 salary 属性为 Number。
有人知道我该如何处理吗?
提前致谢
【问题讨论】:
标签: javascript java arrays rhino