javascript - 将 Rhino Scriptable bean 迁移到 Nashorn

标签 javascript java rhino nashorn

我有一个可编写脚本的 bean,如下所示

package test.rhino;

import java.util.HashMap;

import org.mozilla.javascript.Scriptable;

public class SomeBean implements Scriptable {

    /**
     * The current values for this object.
     */
    private HashMap<String, Object> values = new HashMap<>();

    /**
     * 
     */
    public SomeBean() {
        System.out.println("SomeBean();");
    }

    /*
     * @see org.mozilla.javascript.Scriptable#getClassName()
     */
    @Override
    public String getClassName() {
        return "SomeBean";
    }

    /*
     * @see org.mozilla.javascript.Scriptable#get(java.lang.String,
     * org.mozilla.javascript.Scriptable)
     */
    @Override
    public Object get(String name, Scriptable start) {

        System.out.println("Get is called.");
        System.out.println("Called for this" + name + " and returned :" + values.get(name));

        return values.get(name);
    }

    /*
     * @see org.mozilla.javascript.Scriptable#put(java.lang.String,
     * org.mozilla.javascript.Scriptable, java.lang.Object)
     */
    @Override
    public void put(String name, Scriptable start, Object value) {
        System.out.println("Put is called. Input name: " + name + "\n Input values: " + value);

        values.put(name, value);

    }

    @Override
    public Object get(int index, Scriptable start) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean has(String name, Scriptable start) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean has(int index, Scriptable start) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void put(int index, Scriptable start, Object value) {
        // TODO Auto-generated method stub

    }

    @Override
    public void delete(String name) {
        // TODO Auto-generated method stub

    }

    @Override
    public void delete(int index) {
        // TODO Auto-generated method stub

    }

    @Override
    public Scriptable getPrototype() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void setPrototype(Scriptable prototype) {
        // TODO Auto-generated method stub

    }

    @Override
    public Scriptable getParentScope() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void setParentScope(Scriptable parent) {
        // TODO Auto-generated method stub

    }

    @Override
    public Object[] getIds() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object getDefaultValue(Class<?> hint) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean hasInstance(Scriptable instance) {
        // TODO Auto-generated method stub
        return false;
    }

}

在Rhino中,使用javascript我可以访问底层HashMap中的键作为bean的属性。

var bean = new SomeBean();"
                + "bean.nomen = 'John Doe';\n"
                + "bean.nomen2 = bean.nomen + ' is cool';

输出显示 get 和 put 被称为从 HashMap 'values' 添加和访问的键和值。这样我还可以向 get() 和 put() 方法定义添加附加功能。

在将此 bean 移植到 Nashorn 时,我找不到具有相同功能的方法。 Nashorn 确实在 Javascript 中公开了 HashMap,并允许我们添加条目,但对我来说,这种行为应该可以通过通用的 setter 或 getter 从 bean 实例访问,这样我就可以在从 HashMap 添加和检索值时做更多的事情。

所以它应该像下面这样工作:-

Assume bean = new SomeBean(); 
bean.name = 'John Doe' // Adds name and John Doe to the HashMap
print(bean.name) // Retrieves John Doe. 

有没有办法在 Nashorn 中实现这一点?我知道公共(public)类变量可用于我的 bean 实例,但这并没有给我提供与上面所示相同的功能。我也不想直接访问 HashMap。

谢谢。

最佳答案

经过大量挖掘,我能够通过从“AbstractJSObject”类扩展我的 bean 来解决这个问题。该类具有代理 get、set 以及当我们尝试使用点运算符访问/更改对象属性时将调用的方法。

更改后的类如下所示。

package test.nashorn;

import java.util.HashMap;

import jdk.nashorn.api.scripting.AbstractJSObject;

public class NSomeOtherBean extends AbstractJSObject {

    /**
     * The current values for this object.
     */
    private HashMap<String, Object> values = new HashMap<>();

    public NSomeOtherBean() {
        System.out.println("Constructor called.");
    }

    // do you have a property of that given name?
    @Override
    public boolean hasMember(String name) {
        return has(name);
    }

    // get the value of that named property
    @Override
    public Object getMember(String name) {

        return get(name);

    }

    // get the value of that named property
    @Override
    public void setMember(String name,Object value) {

         put(name,value);

    }

    public Object get(String name) {

        System.out.println("JAVA Get is called.");
        // System.out.println("Called for this"+name+" and returned
        // :"+values.get(name));

        return values.get(name);
    }

    public void put(String name, Object value) {
        System.out.println("JAVA Put is called. Input name: " + name + "\n Input values: " + value);

        values.put(name, value);

    }

    public boolean has(String name) {
        System.out.println("JAVA Has is called. Input name: " + name);

        return values.containsKey(name);

    }
}

关于javascript - 将 Rhino Scriptable bean 迁移到 Nashorn,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37755478/

相关文章:

javascript - Google Map API v3 - 超出最大调用堆栈大小

javascript - 当我们点击它时,轮播所选项目会突出显示(使用 jQuery)

javascript - 使用 ES6Modules 将 * 导出为 *

java - java中多态性的小误区

java - Rhino 范围垃圾何时被收集?

java - 如何将 Rhino-JavaScript 数组转换为 Java 数组

javascript - 通过 ID 获取动态创建的元素 (Jquery)

java - Android:双击会在不应该缩小位图图像的情况下缩小......?

java - 如何使用 bouncy caSTLe 加密数据同时确保结果是确定性的

java - 是否可以使用 RingoJS 将 JavaScript 文件编译为 Java 类文件?