【问题标题】:Java array of Entities to JavaScript arrayJava 实体数组到 JavaScript 数组
【发布时间】: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


    【解决方案1】:

    您可以在服务器端将 Java 对象转换为 JSON 字符串并将其传递给客户端 - javascript。当客户端收到来自服务器的响应(包含您的对象的 JSON 字符串)时,您可以解析 json。

    您可以将 Java 对象转换为 JSON(在服务器端),请查看此教程:

    GSONhttps://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/

    杰克逊https://www.mkyong.com/java/jackson-2-convert-java-object-to-from-json/

    这是在js中解析JSON对象的方法。 https://www.w3schools.com/js/js_json_parse.asp

    我想允许 javascript 用户修改全局变量“entities”。执行用户脚本后,我想将此对象检索回 Java(并稍后执行一些操作)。

    您可以向服务器发出 AJAX 请求,传递修改后的对象。同样,在 js 端,您将这些对象转换为 JSON,然后将它们传递给服务器,并将 JSON 字符串解析为对象的集合(数组)。

    这是如何将 javascript 对象转换为 JSON 字符串 Convert JS object to JSON string

    我有 Java 应用程序,它使用 Rhino(在标签中)。我有 TextArea,用户在其中键入 JS 代码。我需要给用户实体对象。

    因此,将用户输入的文本传递到您的服务器,并对其进行解析。不过请确保您传递的是有效的 JSON。

    【讨论】:

      【解决方案2】:

      取决于你的 JS 版本,你可以这样做:

      ES5

      function Person(firstName, lastName, salary, email) {
              this.firstName = firstName;
              this.lastName = lastName;
              this.salary = salary;
              this.email = email;
          }
      
      var john = new Person("john", "smith", 500, "john.smith@john.com");
      var jane = new Person("jane", "doe", 650, "jane.doe@jane.net");
      var people = [john, jane];
      
      //mutating the original values
      people.forEach(function(person) {person.salary += 500})
      

      ES6

      class Person {
        constructor(firstName, lastName, salary, email) {
          this.firstName = firstName;
              this.lastName = lastName;
              this.salary = salary;
              this.email = email;
        }
      }
      
      let john = new Person("john", "smith", 500, "john.smith@john.com");
      let jane = new Person("jane", "doe", 650, "jane.doe@jane.net");
      let people = [john, jane];
      
      people.forEach(person => person.salary += 500);
      

      【讨论】:

      • 你一定是误解了这个问题。我不想在 JS 中定义所有的构造函数。我想将由实体组成的 JAVA 对象映射到 JavaScript 中,我可以在其中修改它们。
      • 您有 JAVA 中的数据 - 并且希望将其传递给浏览器?为什么不使用 github.com/google/gson 之类的东西?浏览器非常适合 JSON,因为它只是一个普通的 JS 对象。
      • 我有 Java 应用程序,它使用 Rhino(在标签中)。我有 TextArea,用户在其中键入 JS 代码。我需要给用户entities 对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-26
      • 2018-12-25
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多