使用GSON的JSON字符串到Java对象

时间:2013-05-23 20:19:35

标签: java json parsing gson

我正在尝试将json解析为java。

根据jsonlint.com,我有以下字符串是有效的json

private final static String LOC_JSON = 
         "["
        +"{"
        +"  \"lat1\": 39.737567,"
        +"  \"lat2\": 32.7801399,"
        +"  \"long1\": -104.98471790000002,"
        +"  \"long2\": -96.80045109999998"
        +"},"
        +"  ["
        +"      {"
        +"          \"lat\": {"
        +"              \"b\": 38.88368709500021,"
        +"              \"d\": 40.620468491667026"
        +"          },"
        +"          \"long\": {"
        +"          \"b\": -105.75306170749764,"
        +"          \"d\": -104.675854661387"
        +"          }"
        +"      }"
        +"  ]"
        +"]";

我正在尝试将其解析为一个对象,我收到以下错误。 “预计BEGIN_OBJECT但在第1行第2列是BEGIN_ARRAY”

            Gson gson = new Gson();
        BoxSearch b = gson.fromJson( LOC_JSON, BoxSearch.class ); 

BoxSearch由此组成。

private Number lat1;
private Number lat2;
private Number long1;
private Number long2;
private Boxes[] boxes;

Boxes是Latitude对象和Longitude对象,两者都定义相同。

private String b;
private String d;

我可以将更高级别的属性(lat1,lat2,long1和long2)解析为一个只有4个属性的更简单的BoxSearch对象。当json和对象更复杂时会出现问题。是否有可能做我正在尝试的事情?

我希望我提供了足够的信息来获得帮助。如果需要,我很乐意提供更多信息甚至是测试项目。我将其作为junit测试运行。

感谢。

2 个答案:

答案 0 :(得分:23)

Gson gson = new Gson();
gson.fromJson(jsonStr,YourClass.class);
很容易。

答案 1 :(得分:19)

错误的原因是顶层的JSON是一个数组,而不是一个对象。这由GSON throwing "Expected BEGIN_OBJECT but was BEGIN_ARRAY"?涵盖。

但是,那里的解决方案对你的JSON不起作用,因为你有一个混合类型(一个对象和一个数组)的数组,而不是一个单一类型的对象的数组。为此,您将不得不编写自定义反序列化器(请参阅The section of the Gson user's guide that covers this)或直接使用Gson的JsonParser类,并从解析树中提取数据。

根据上述评论进行修改:

如果您是创建JSON的人,那么看起来就像您想要的是BoxSearch个对象的数组一样?

基于您的Java BoxSearch类,您需要JSON结构如下:

[
    {
        "lat1" : 39.737567,
        "lat2" : 32.7801399,
        "long1" : -104.98471790000002,
        "long2" : -96.80045109999998,
        "boxes" : [ 
                    {
                      "lat": {
                          "b": 38.88368709500021,
                          "d": 40.620468491667026
                      },
                      "long": {
                          "b": -105.75306170749764,
                          "d": -104.675854661387
                      }
                    }
                  ]
    }
]

但是,定义Boxes类的方式不适用于此。 (你的意思是有一个阵列?)。原样它需要看起来像:

class Boxes {
    Box lat;
    @SerializedName("long")
    Box lon;
}

class Box {
   String b;
   String d;
}

现在你有一个包含一种类型的对象(BoxSearch)的数组,您可以使用它反序列化:

Type collectionType = new TypeToken<Collection<BoxSearch>>(){}.getType();
Collection<BoxSearch> boxSearchCollection = gson.fromJson(json, collectionType);

如果你真的不需要这些数组,可以去掉外部数组,然后执行:

gson.fromJson(json, BoxSearch.class);