JSON字符串化在GWT的ArrayList然后返回数组

问题描述 投票:0回答:1

目前尝试使用的互操作的方法来调用本机JSON.stringify(ArrayListobj)以字符串化在GWT一个Java ArrayList对象。这导致在阵列形式的底层数组列表内容的完美JSON表示。这甚至适用于看似更复杂的Java类的对象,但在这种情况下我会使用字符串来证明。首先在我的创作方:

test = new ArrayList<>();
test.add("first");
test.add("second");
String jsonstr = JSON.stringify(test);

现在根据我JsInterop代码,我返回一个对象(或对象数组是在这里显示的代码的情况下):

@JsType(isNative=true, namespace=GLOBAL)
public class JSON {
  public native static String stringify(Object obj);
  public native static Object[] parse(String obj);
}

到目前为止好,这一切完美的作品,和我得到的结果的ArrayList内容字符串化JSON表示

“{” array_0 “:[” 第一 “ ”第二“]}”

然后运行通过解析器此位:

ArrayList<String> returned = new ArrayList<>();
Object[] var = JSON.parse(jsonstr);

和VAR从第一ArrayList中的基础数据的正确reprsentation(当在看网页浏览器执行暂停)。问题越来越对象[JSON数组的]转换回Java ArrayList对象。

我一直在使用JSNI代码提取数组元素,这实际上在Web浏览器的控制台托盘完美的作品尝试过,但compliler试图智取我并重命名的数组元素,所以我JSNI代码不能触摸它。

如果我的代码如上,和我写JSNI类似:

    public static native ArrayList objToList(ArrayList add,Object inVal) /*-{
         var length = inVal.array.length;
         for(var i = 0;i < length; i++){
             add.array[i] = inVal.array[i];
         }
         return add;
     }-*/;

那么编译器将重命名的数组array_0所以我的代码,说inVal.array不再与我试图访问数据连接线英寸

从所有的测试中,我已经做了,这是迄今为止得到同样的ArrayList对象(其保证在这两个地方被定义相同)的客户端软件从客户端软件的一个地方到另一个地方(没有服务器的最快方法这里)通过字串参与。

但是关于如何操作的JavaScript在GWT低水平的信息,在最好的缺乏。

我累了,在GWT-RPC机制每变化,GWT-杰克逊,AutoBeans(只要他们支持与多个原始类型的对象!)requestbuilder,你的名字。

也没有,你认为它之前,我没兴趣再做字符串的完整GWT-JSON解析,我已经做了,当最初拉动几千条记录。关闭服务器,将他们推到Java的ArrayList。它采用200个+ MS解析JSON的GWT,而浏览器JSON解析函数处理此字符串周围3毫秒。

java json gwt gwt-jsinterop
1个回答
2
投票

GWT使用类型标记跟踪的类型和能够做到类转换安全。你绝不能使用字符串化的Java类,因为你会失去这些类型的标记,你也将使用内部最小化/编码符号。所以,这是GWT内部是怎样处理所有这些类型:

List<String> list = new ArrayList<>();
list.add("a"); list.add("b");
console.log("list", list);
console.log("array", list.toArray());
console.log("stringify", Global.JSON.stringify(list.toArray()));
console.log("parse", Global.JSON.parse(Global.JSON.stringify(list.toArray())));

console ouput的“清单”包含混淆变量array_8_g$,这可能会改变,所以你永远应该使用这种编码。该array结果是正确的,但你应该注意到它包含各种属性(typemarker,casteableTypeMap和__clazz),这些额外的属性被用来使Java铸造的作品,但不枚举因此不包括在接下来的结果stringify。这stringify结果可以解析回作为String[],但现在的结果在parse没有包括塔伊类型的标记属性。所以,如果你立即保存在parse变量String[]的结果,它会正常工作。但是,如果你将它转换为Object并尝试投-IT-回String[]就会失败。

在jsinterop:基地的依赖有2个实用程序的js#铸造和JS#uncheckedCast是在这些情况下很有帮助。如果阵列有一个类型的标记,你可以用js#投(这个工具是一样的标准Java铸造),如果没有,你必须用JS#uncheckedCast。

在这个例子中,第一行会成功,第二个失败的一类强制转换异常:

console.log("uncheck", Js.<String[]>uncheckedCast(JSON.parse(JSON.stringify(list.toArray())))[0]);
console.log("check", Js.<String[]>cast(JSON.parse(JSON.stringify(list.toArray())))[0]);

你真的应该尽量避免混合原生JS代码与Java。如果你需要做的,那么你必须了解的GWT如何处理类型的内部,你必须了解JSNI但用它尽可能少终于明白JsInterop是如何工作的,并用它来访问本地的JS代码或将Java代码在JS世界。

© www.soinside.com 2019 - 2024. All rights reserved.