使用Java解析JSON

4

我是一个对 JSON 解析很陌生的新手,我从一个请求中获取了一个 JSON 字符串,现在需要用 Java 进行解析。我打算使用 json-lib 库来完成这个任务,但由于不熟悉这个库,所以卡住了。我需要提取以下数据:

1. name (hotel name)
2. starRating
3. geoPoint

我用以下Java代码尝试了一下,但是没有得到我需要的结果,请有人帮忙一下...
非常感谢!
Java代码(s是我获取的JSON字符串):
JSONObject json = (JSONObject) JSONSerializer.toJSON(s);    
JSONArray jarray = json.getJSONArray("hotels");
for(int i=0 ; i < jarray.size(); i++) {
System.out.println("jarray [" + i + "] --------" + jarray.getString(i));
}

我需要解析的JSON

[
{
    "total": 250,
    "offset": 0,
    "requestID": "-btygi09oxfov",
    "locationName": "Paris, France",
    "locationLatitude": 48.86,
    "locationLongitude": 2.34,
    "cityCode": "PARIS_J_FR",
    "hotels": [
        {
            "ypid": "YN10001x300073304",
            "id": 56263,
            "hotelRateIndicator": "2",
            "name": "Renaissance Paris Vendome Hotel",
            "brandCode": "69",
            "addressLine1": "4 Rue du Mont-Thabor",
            "city": "Paris",
            "neighborhood": "",
            "state": "IdF",
            "country": "US",
            "cachedPrice": 935,
            "geoPoint": [
                48.865361,
                2.329584
            ],
            "starRating": "5",
            "thumbnailUrl": "http://www.orbitz.com//public/hotelthumbnails/53/97/85397/85397_TBNL_1246535840051.jpg",
            "total": 250,
            "amenities": [
                "24",
                "31",
                "42",
                "52",
                "9"
            ],
            "telephoneNumbers": [
                ""
            ],
            "popularity": 837
        },
        {
            "ypid": "YN10001x300073331",
            "id": 112341,
            "hotelRateIndicator": "3",
            "name": "Renaissance Paris Arc de Triomphe Hotel",
            "brandCode": "69",
            "addressLine1": "39 Avenue de Wagram",
            "city": "Paris",
            "neighborhood": "",
            "state": "IdF",
            "country": "US",
            "cachedPrice": 633,
            "geoPoint": [
                48.877107,
                2.297451
            ],
            "starRating": "5",
            "thumbnailUrl": "http://www.orbitz.com//public/hotelthumbnails/21/72/302172/302172_TBNL_1246535872514.jpg",
            "total": 250,
            "amenities": [
                "24",
                "31",
                "42",
                "9"
            ],
            "telephoneNumbers": [
                ""
            ],
            "popularity": 796
        }           
  ]         
}           
  ]

2
有什么问题?你是否遇到了错误?或者没有得到所需的数据? - aldrin
@adrin:我遇到了一个异常,线程中出现了 java.lang.ClassCastException 异常:net.sf.json.JSONArray 无法转换为 net.sf.json.JSONObject。 - Pavithra Gunasekara
5个回答

6
任何 JSON 对象都可以表示为一个 Map<String, Object>
使用像 jackson 这样的库(与 Spring 一起提供),它可以将 JSON 反序列化为如下的 Map:
Map<String, Object> obj = new ObjectMapper().readValue(json, new TypeReference<Map<String, Object>>());

或者使用较慢的、但带有 Google 品牌的GSON,可以像这样使用。

Map<String, Object> obj = new Gson().fromJson(json, HashMap.class);

1
谢谢您的建议,但我处于必须使用json-lib的情况下 :) - Pavithra Gunasekara
1
哎呀——两个踩?老实说,gson 能够轻松地从 JSON 中构建 Java 对象,反之亦然。不管怎样... - Bohemian
我刚刚对Java中一些最受欢迎的JSON库进行了基准测试。当我看到GSON是最不具备现代化性能的库时,我感到震惊(还有更老旧和更糟糕的库)。如果你不相信,请自行查看:https://github.com/fabienrenaud/java-json-benchmark 我一直认为Jackson和GSON在性能上类似...但在这张图片中,Jackson显然是赢家。 - fabien
@fab 很好,因为我发布这个答案以来,我一直在使用jackson,不是因为它更快,而是因为它与Spring Boot一起提供了开箱即用的功能,而我最近几年一直在使用Spring Boot。我已经更新了答案,包括jackson和指向您基准测试的链接。 - Bohemian

5
要解决ClassCastException问题,您只需要按照提示所说的进行更改:将输入处理为数组而不是对象。
JSONArray outerArray = (JSONArray) JSONSerializer.toJSON(s);
JSONObject json = (JSONObject) outerArray.get(0);
JSONArray jarray = json.getJSONArray("hotels");
for (int i = 0; i < jarray.size(); i++)
{
  System.out.println("jarray [" + i + "] --------" + jarray.getString(i));
}

这里有一个获取每个酒店名称的示例。
JSONArray outerArray = (JSONArray) JSONSerializer.toJSON(s);
JSONObject json = (JSONObject) outerArray.get(0);
JSONArray jarray = json.getJSONArray("hotels");
for (int i = 0; i < jarray.size(); i++)
{
  JSONObject hotel = jarray.getJSONObject(i);
  String name = hotel.getString("name");
  System.out.println(name);
}

0

我已经开始了一个名为JsonQuery的Github项目,使得这种操作变得更加容易。

该项目建立在GSON之上。

例如,如果您想要检索酒店的名称,只需要像这样简单的代码:

JsonQuery $ = JsonQuery.fromJson(s); 
$.val("hotels.name");

这是链接:

https://github.com/rdbeach/JsonQuery


0

我推荐使用Djson解析器(Java库)。 https://github.com/jungkoo/djson_parser

代码:

Var hotels = Djson.parse(new File("d:\\sample1.txt")).find("[0].hotels");

for(int i=0; i<hotels.size(); i++) {            
  System.out.println(hotels.get(i).get("name").toString());
  System.out.println(hotels.get(i).get("starRating").toInt());
  System.out.println(hotels.get(i).find("geoPoint").get(0).toDouble()); // case1) basic
  System.out.println(hotels.get(i).find("geoPoint[1]").toDouble()); // case2) find()    
  System.out.println();
}

输出:

Renaissance Paris Vendome Hotel 5
48.865361
2.329584

Renaissance Paris Arc de Triomphe Hotel 5
48.877107
2.297451

0

下载json-lib并使用JSONObject

假设有{"name": "joe", "age": 33}

操作如下:

JSONObject jobject=new JSONObject(jsonstring);
String name=jobject.getString("name");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接