2

我有一个二维数组,我在 GWT 中将其表示为 type 的对象JsArray<JsArrayNumber>。如果我要将数组转换为 Javascript,它看起来像这样:

var test = [[0.6578396255487482,7.875995798E-314,3.1688557021480858E55],
                [9.365832954E-315,0.9866897170404328,9.378991533366766E54],
            [4.999803162025956E51,6.32672779777942E54,1.987536773023561]];

问题是,当我尝试使用 将 GWT 对象序列化为 JSON 字符串时JSONObject.toString(),进程挂起并且永远不会完成。通过一些混乱,我发现如果我将非常小的数字(以 E-315 结尾的数字)更改为零,则序列化成功完成。为什么 GWT 很难处理这些数字?JSONObject.toString()序列化这样的东西的正确方法是什么?我意识到,由于这些数字非常小,我可以在序列化之前对这些对象进行清理,但如果可能的话,我不希望更改它们,因为它们是某种敏感计算的结果。

编辑:

这是一个显示行为的示例单元测试:

import org.junit.Test;

import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.junit.client.GWTTestCase;

public class SmallDoubleTest extends GWTTestCase{

    @Test
    public void test(){

        // When the very small numbers are replaced with 0 everything works
        String jsonStr = "[[0.6578396255487482,0,3.1688557021480858E55]," +
                        "[0,0.9866897170404328,9.378991533366766E54]," +
                        "[4.999803162025956E51,6.32672779777942E54,1.987536773023561]]";
        JsArray<JsArrayNumber> jsobj = buildArray(jsonStr);
        System.out.println("First Item: " + jsobj.get(0).get(0));
        System.out.println("Last Item: " + jsobj.get(2).get(2));
        JSONObject jsonobj = new JSONObject(jsobj);
        System.out.println(jsonobj.toString());

        // Putting them back in cause everything to hang on jsonobj.toString();
        jsonStr = "[[0.6578396255487482,7.875995798E-314,3.1688557021480858E55]," +
                         "[9.365832954E-315,0.9866897170404328,9.378991533366766E54]," +
                         "[4.999803162025956E51,6.32672779777942E54,1.987536773023561]]";
        jsobj = buildArray(jsonStr);
        System.out.println("First Item: " + jsobj.get(0).get(0));
        System.out.println("Last Item: " + jsobj.get(2).get(2));
        jsonobj = new JSONObject(jsobj);
        System.out.println(jsonobj.toString());
    }

    public static native JsArray<JsArrayNumber> buildArray(String json) /*-{
        return eval('(' + json + ')');
    }-*/;


    public String getModuleName(){
        return "com.iai.cgs.rest.gwtclient.CGSGWTClient";
    }
}
4

3 回答 3

2

我可能会建议问题出在JSONObject实现上,因为它总是尝试从提供的数据手动创建 json。我很确定使用本机浏览器JSON.stringify()功能会快得多。例子:

public static native String stringify(JavaScriptObject object)/*-{
   return JSON.stringify(object);
}-*/;

唯一的问题是旧的浏览器(比如 IE6-7)不支持这个功能

于 2012-12-07T21:37:33.467 回答
0

对于一个JsArray你必须使用new JSONArray(jsobj).toString(),而不是JSONObject.

于 2012-12-07T22:26:42.253 回答
0

正如 JSONArray 的 JavaDoc 已经警告的那样,如果数组很大, toString() 可能需要很长时间(尽管您可能不会使用 JSONArray,但 toString 对于 JSON 对象可能很昂贵。如果您有 JsArray,您可以尝试以下join方法还返回一个字符串,它只是原生 JavaScript,可能会更快。

于 2012-12-07T21:25:58.983 回答