10

我正在尝试使用 gson 将此返回的 JSON 转换为某种数据结构,以便我可以提取有用的数据。

例如:

http://search.twitter.com/search.json?q=test&rpp=1

回报:

{
    "completed_in":0.028,
    "max_id":196386333906837504,
    "max_id_str":"196386333906837504",
    "next_page":"?page=2&max_id=196386333906837504&q=test&rpp=1",
    "page":1,
    "query":"test",
    "refresh_url":"?since_id=196386333906837504&q=test",
       "results":[
          {
             "created_at":"Sat, 28 Apr 2012 23:52:05 +0000",
             "from_user":"della_ky",
             "from_user_id":525641596,
             "from_user_id_str":"525641596",
             "from_user_name":"kydella modeste",
             "geo":null,
             "id":196386333906837504,
             "id_str":"196386333906837504",
             "iso_language_code":"en",
             "metadata":{
                "result_type":"recent"
             },
             "profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2159990525\/webcam-toy-photo3_20_2__normal.jpg",
             "profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2159990525\/webcam-toy-photo3_20_2__normal.jpg",
             "source":"<a href="http:\/\/mobile.twitter.com" rel="nofollow">Mobile Web<\/a>",
             "text":"RT @Y__U__NOOO: #SongsIKnowOffByHeart ALL SONGS I LISTEN TO. BRAIN, Y U NO REMEMBER TEST ANSWERS LIKE THAT?!?",
             "to_user":null,
             "to_user_id":null,
             "to_user_id_str":null,
             "to_user_name":null
          }
       ],
       "results_per_page":1,
       "since_id":0,
       "since_id_str":"0"
    }

最终,我希望能够输出带有发件人姓名和推文日期/时间的推文列表。

我已经通读了 gson 文档,但老实说,这让我头疼——那里有很多新概念。

我是否需要定义一个完全映射到 JSON 结构的类,然后才能填充该类的实例?如果是这样,这似乎非常不灵活/费力。理想情况下,我正在寻找可以处理任何形式的 JSON 并给我一个可以自动使用的结构的东西......

有人能给我一些指示吗?作为新手 - 越详细,用最少的音节就越好!

更新 - 感谢我已经收到的回复,我已经尝试将一个类放在一起来捕获 twitter JSON。但是,由于 JSON 有一个嵌入的 ArrayList 对象我有点挣扎......到目前为止我有

public class tweetData {
    private double completed_in;
    private long max_id;
    private long max_id_str;
    private String next_page;
    private int page;
    private String query;
    private String refresh_url;
    private List<tweetDetails> tweets = new ArrayList<tweetDetails>();
}

public class tweetDetails {
    private String created_at;
    private String from_user;
    private long from_user_id;
    private long from_user_id_str;
    private String from_user_name;
    private String geo;
    private long id;
    private long id_str;
    private String iso_language_code;
//  "metadata":
//  {
//  "result_type":"recent"
//  },
    private String profile_image_url;
    private String profile_image_url_https;
    private String source;
    private String text;
    private String to_user;
    private String to_user_id;
    private String to_user_id_str;
    private String to_user_name;
}

我正在实例化

URI uri = new URI("http", "search.twitter.com", "/search.json", "q="+ searchTerms + "&rrp=" + RRP, null);
URL twitterSearch = uri.toURL();
URLConnection yc = twitterSearch.openConnection();
JsonReader reader = new JsonReader(new InputStreamReader(yc.getInputStream()));
Gson gson = new Gson();
tweetData data = gson.fromJson(reader, tweetData.class);
System.out.println(data);

基本名称:值已正确填充,但 ArrayList 未正确填充。

tweetData : 0.17196614959919140865196614959919140865?page=2&max_id=196614959919140865&q=test1test?since_id=196614959919140865&q=testSIZE 0[]

所以,我仍然有点挣扎 - 任何更多的提示都非常感谢!

蒂亚,汤姆

4

4 回答 4

10

我是否需要定义一个完全映射到 JSON 结构的类,然后才能填充该类的实例?如果是这样,这似乎非常不灵活/费力。

是的。GSON是一个库,可用于将 Java 对象转换为其 JSON 表示形式。它还可用于将 JSON 字符串转换为等效的 Java 对象。这非常强大,因为您可以从 JSON 表示中自动实例化您的 Java 对象。假设您的 JSON 不改变其结构,您只需定义一次适当的 Java 对象表示。

理想情况下,我正在寻找可以处理任何形式的 JSON 并给我一个可以自动使用的结构的东西......

但是,如果您不想要自动序列化/反序列化,请尝试查看更简单的库,例如java.net/projects/jsonp

您可以通过查询键从中提取内容:

final JSONObject json = new JSONObject(theJsonString);
final String id = json.getString("max_id");
final JSONArray results = json.getJSONArray("results");
final String user = results.getJSONObject(2).getString("from_user");
于 2012-04-29T02:14:48.773 回答
3

Gson 实际上为您完成了所有的序列化。所以是的,您必须自己编写课程。对您来说,这看起来既不灵活又费力,但这仅仅是因为该库不是为您所要求的而设计的(它不会解析“任意”JSON)。

我建议至少考虑编写课程并使用 gson。我这么说的原因是因为无论哪种方式,您的应用程序逻辑都必须期待一种非常具体的格式,并且在 Java 类中写出该格式会使事情变得更整洁。这是一个很好的指南,可以帮助您以这种方式开始。

如果您想简单地解码 JSON 而不将其序列化为 Java 类(恕我直言,这是使用“任意”JSON 的唯一方法),您将需要使用另一个库。试试这个。它允许您解码 JSON,并通过从中获取值来使用它(如本问题所述:Convert a JSON string to object in Java ME?)。

于 2012-04-29T02:14:29.580 回答
2

有一些工具可以进行 gson 到模式映射。您提供一些示例 JSON 响应,并为您创建访问它们的 java 类。

http://www.jsonschema2pojo.org/

于 2015-05-24T20:43:34.050 回答
1

Gson是一个狡猾的野兽!或者至少在这个问题被问到之后的几年里变得如此。

您可以将Object.class作为第二个参数传递给fromJson()方法,它会将您的 Json 解析为LinkedTreeMapArrayList的合理结构。

Object result = (new Gson()).fromJson(jsonString, Object.class)

不仅如此,您还可以通过将某个字段定义为 Object来真正进行部分解析并在对象结构的任何级别留下松散的结尾!

然后, Gson会将 Json 解析为您的结构,并且您的 Object 类型字段将包含上述LinkedTreeMapArrayList的结构。

例如,您可以定义一个类

Person {
    String name;
    Object details;
}

(想象一下,你主要关心这个人的名字,但也可能在某个地方想要详细信息。例如,记录他们。)

然后您可以将以下 Json作为第一个参数传递给fromJson(input, Person.class)方法

{ 
    "name": "Carlsson", 
    "details": {
        "address": "Stockholm",
        "phones": [
            "work": "233-322-233-322",
            "home": "none"
        ]
    }
}

结果将具有填充“Carlsson”字符串的名称字段,详细信息字段将包含带有键“address”“phones”等的LinkedTreeMap 。

于 2018-03-02T20:07:45.930 回答