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);

基本的な name:values は正しく取り込まれていますが、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 オブジェクト表現を1 回定義するだけで済みます。

理想的には、任意の形式で 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クラスにシリアル化せずに単純にデコードしたい場合(IMHOが「任意の」JSONを使用する唯一の方法です)、別のライブラリを使用する必要があります。これを試してみてください。これにより、JSON をデコードし、そこから値を取得して使用できます (この質問で説明されているように: JSON 文字列を 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を 2 番目のパラメーターとしてfromJson()メソッドに渡すと、Json が解析されてLinkedTreeMapおよびArrayListの妥当な構造になります。

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

それ以上に、特定のフィールドを Object として定義することにより、部分的な解析を実際に実行し、オブジェクト構造の任意のレベルで未解決のままにすることができます!

次に、 Gsonは Json を構造に解析し、タイプ Object のフィールドには、上記のLinkedTreeMapおよびArrayListの構造が含まれます。

たとえば、クラスを定義できます

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 に答える