Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Java映射转换为基本Javascript对象?_Java_Javascript_Rhino - Fatal编程技术网

如何将Java映射转换为基本Javascript对象?

如何将Java映射转换为基本Javascript对象?,java,javascript,rhino,Java,Javascript,Rhino,我开始在Java6中使用DynamicRhinoscript特性,以供更可能了解Javascript而不是Java的客户使用 将映射(关联数组、javascript obj等)传递到javascript中以便脚本编写者可以使用标准javascript点符号访问值的最佳方法是什么 我目前正在将值的java.util.Map传递到脚本中,但是脚本编写器必须编写“Map.get('mykey')”而不是“Map.mykey” 基本上,我想做与之相反的事情,你只需要将你的对象编码为,或者手动编码,或者使

我开始在Java6中使用DynamicRhinoscript特性,以供更可能了解Javascript而不是Java的客户使用

将映射(关联数组、javascript obj等)传递到javascript中以便脚本编写者可以使用标准javascript点符号访问值的最佳方法是什么

我目前正在将值的java.util.Map传递到脚本中,但是脚本编写器必须编写“Map.get('mykey')”而不是“Map.mykey”


基本上,我想做与之相反的事情,你只需要将你的对象编码为,或者手动编码,或者使用像或这样的库。正如您所说,这正是问题的关键所在,而问题的作者对JSON符号不满意:)

您需要发送到浏览器的内容基本上如下所示:

var someObject = { "key1": "value1", "key2": "value2", ... }

然后javascript开发人员可以简单地访问:
someObject.key2

我采用了Java NativeObject方法,下面是我所做的

// build a Map
Map<String, String> map = new HashMap<String, String>();
map.put("bye", "now");

// Convert it to a NativeObject (yes, this could have been done directly)
NativeObject nobj = new NativeObject();
for (Map.Entry<String, String> entry : map.entrySet()) {
    nobj.defineProperty(entry.getKey(), entry.getValue(), NativeObject.READONLY);
}

// Get Engine and place native object into the context
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("javascript");
engine.put("map", nobj);

// Standard Javascript dot notation prints 'now' (as it should!)
engine.eval("println(map.bye);");
//构建一个映射
Map Map=newhashmap();
地图。放(“再见”,“现在”);
//将其转换为NativeObject(是的,这可以直接完成)
NativeObject nobj=新的NativeObject();
对于(Map.Entry:Map.entrySet()){
nobj.defineProperty(entry.getKey()、entry.getValue()、NativeObject.READONLY);
}
//获取引擎并将本机对象放置到上下文中
ScriptEngineManager工厂=新ScriptEngineManager();
ScriptEngine=factory.getEngineByName(“javascript”);
引擎放置(“地图”,nobj);
//标准Javascript点符号打印“现在”(应该如此!)
engine.eval(“println(map.bye);”;

我使用一个实用程序类将映射转换为javascript哈希对象:

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.mozilla.javascript.Scriptable;
public class MapScriptable implements Scriptable, Map {
    public final Map map;
    public MapScriptable(Map map) {
        this.map = map;
    }
    public void clear() {
        map.clear();
    }
    public boolean containsKey(Object key) {
        return map.containsKey(key);
    }
    public boolean containsValue(Object value) {
        return map.containsValue(value);
    }
    public Set entrySet() {
        return map.entrySet();
    }
    public boolean equals(Object o) {
        return map.equals(o);
    }
    public Object get(Object key) {
        return map.get(key);
    }
    public int hashCode() {
        return map.hashCode();
    }
    public boolean isEmpty() {
        return map.isEmpty();
    }
    public Set keySet() {
        return map.keySet();
    }
    public Object put(Object key, Object value) {
        return map.put(key, value);
    }
    public void putAll(Map m) {
        map.putAll(m);
    }
    public Object remove(Object key) {
        return map.remove(key);
    }
    public int size() {
        return map.size();
    }
    public Collection values() {
        return map.values();
    }
    @Override
    public void delete(String name) {
        map.remove(name);
    }
    @Override
    public void delete(int index) {
        map.remove(index);
    }
    @Override
    public Object get(String name, Scriptable start) {
        return map.get(name);
    }
    @Override
    public Object get(int index, Scriptable start) {
        return map.get(index);
    }
    @Override
    public String getClassName() {
        return map.getClass().getName();
    }
    @Override
    public Object getDefaultValue(Class<?> hint) {
        return toString();
    }
    @Override
    public Object[] getIds() {
        Object[] res=new Object[map.size()];
        int i=0;
        for (Object k:map.keySet()) {
            res[i]=k;
            i++;
        }
        return res;
    }
    @Override
    public Scriptable getParentScope() {
        return null;
    }
    @Override
    public Scriptable getPrototype() {
        return null;
    }
    @Override
    public boolean has(String name, Scriptable start) {
        return map.containsKey(name);
    }
    @Override
    public boolean has(int index, Scriptable start) {
        return map.containsKey(index);
    }
    @Override
    public boolean hasInstance(Scriptable instance) {
        return false;
    }
    @Override
    public void put(String name, Scriptable start, Object value) {
        map.put(name, value);
    }
    @Override
    public void put(int index, Scriptable start, Object value) {
        map.put(index, value);
    }
    @Override
    public void setParentScope(Scriptable parent) {}
    @Override
    public void setPrototype(Scriptable prototype) {}
}

在了解到
SimpleScriptContext
将只接受
Map
对象,从而迫使您在JavaScript中使用Java方法之后,下面是我所做的

Map<String, String> myMap = new HashMap<String, String>();
myMap.put("test", "hello world!");

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
Object eval = engine.eval("var map = " + new Gson().toJson(myMap) + ";\n" 
    + "println(map.test);");

谢谢你的快速回复!这在向浏览器发送JSON时效果很好,但在服务器上效果不太好。下面是我的示例:`ScriptEngineManager工厂=new ScriptEngineManager();ScriptEngine=factory.getEngineByName(“javascript”);engine.put(“obj”,“key1\”:“value1\”,“key2\”:“value2\”);//这将返回“string”而不是“obj”。我不想让脚本编写器评估字符串,尽管我可能不得不这样做。发动机评估(“类型(obj)”;“我也是这样做的,但使用了杰克逊。我现在有点担心性能,因为脚本总是在变化。理论上,可以将Jackson的对象映射功能与
NativeObject
(@JonCarlson)支持结合使用,以缓解性能问题。另一个选项是编写一个递归遍历哈希映射的通用javascript。这似乎不起作用。它写的是“未定义”。我仍然需要使用get方法访问属性:map.get('bye')。另请参见
Map<String, String> myMap = new HashMap<String, String>();
myMap.put("test", "hello world!");

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
Object eval = engine.eval("var map = " + new Gson().toJson(myMap) + ";\n" 
    + "println(map.test);");
hello world!