如何将任意 JSON 转换为 Java 中可用的结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10368619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert arbitrary JSON into a usable structure in Java
提问by Tom
I'm trying to use gson to convert this returned JSON into some kind of data structure such that I can extract useful data.
我正在尝试使用 gson 将此返回的 JSON 转换为某种数据结构,以便我可以提取有用的数据。
For Example:
例如:
http://search.twitter.com/search.json?q=test&rpp=1
http://search.twitter.com/search.json?q=test&rpp=1
Returns:
返回:
{
"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"
}
Ultimately, I would like to be able to output a list of tweets with the name of the sender and the date/time of the tweet.
最终,我希望能够输出带有发件人姓名和推文日期/时间的推文列表。
I have read through the gson documentation but it's going over my head to be honest - lots of new concepts there for me.
我已经通读了 gson 文档,但老实说,这让我无法理解 - 对我来说有很多新概念。
Do I need to define a class which maps exactly to the structure of the JSON in order to then populate an instance of that class? If so this seems very inflexible/laborious. Ideally I'm looking for something which will handle JSON in any form and give me a structure I can use automatically...
我是否需要定义一个完全映射到 JSON 结构的类,以便填充该类的实例?如果是这样,这似乎非常不灵活/费力。理想情况下,我正在寻找可以处理任何形式的 JSON 并给我一个可以自动使用的结构的东西......
Is anyone able to give me some pointers? Being new to this - the more detailed and in words of the fewest syllables the better!
有人能给我一些指点吗?刚接触这个 - 越详细,字数越少越好!
Update - Thanks to the responses I've already had on this I've had a go at putting a class together to capture the twitter JSON. However, since the JSON has an embedded ArrayList of Objects I'm struggling a bit... So far I have
更新 - 由于我已经对此做出了回应,我已经尝试将一个类放在一起来捕获 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>();
}
and
和
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;
}
Which I'm instantiating with
我正在实例化
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);
The basic name:values are being populated correctly but the ArrayList is not.
基本名称:值被正确填充,但 ArrayList 不是。
tweetData : 0.17196614959919140865196614959919140865?page=2&max_id=196614959919140865&q=test1test?since_id=196614959919140865&q=testSIZE 0[]
So, I'm still struggling a bit - any more tips hugely appreciated!
所以,我仍然有点挣扎 - 非常感谢更多提示!
Tia, Tom
蒂亚,汤姆
采纳答案by Greg Kopff
Do I need to define a class which maps exactly to the structure of the JSON in order to then populate an instance of that class? If so this seems very inflexible/laborious.
我是否需要定义一个完全映射到 JSON 结构的类,以便填充该类的实例?如果是这样,这似乎非常不灵活/费力。
Yes. GSONis a library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. This is really powerful because you can automagically instantiate your Java objects from the JSON representation. Assuming your JSON doesn't change its structure, you only have to define the appropriate Java object representation once.
是的。GSON是一个可用于将 Java 对象转换为其 JSON 表示的库。它还可用于将 JSON 字符串转换为等效的 Java 对象。这真的很强大,因为您可以从 JSON 表示自动实例化 Java 对象。假设您的 JSON 不改变其结构,您只需定义适当的 Java 对象表示一次。
Ideally I'm looking for something which will handle JSON in any form and give me a structure I can use automatically...
理想情况下,我正在寻找可以处理任何形式的 JSON 并给我一个可以自动使用的结构的东西......
However, if you don't want automagical serialisation/deserialisation, then try looking at a simpler library such as java.net/projects/jsonp.
但是,如果您不想要自动序列化/反序列化,请尝试查看更简单的库,例如java.net/projects/jsonp。
You can extract stuff from it just by querying the keys:
您只需通过查询键即可从中提取内容:
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");
回答by Hassan
Gson actually does all the serialization for you. So yes, you would have to write the classes yourself. To you, this seams inflexible and laborious, but that's only because that library isn't made for what you're asking for (it doesn't parse 'arbitrary' JSON).
Gson 实际上为你做了所有的序列化。所以是的,你必须自己编写类。对您来说,这接缝不灵活且费力,但这只是因为该库不是为您所要求的(它不解析“任意”JSON)而设计的。
I would suggest at least considering writing the classes and using gson. The reason I say that is because either way your application's logic will have to expect a very specific format, and writing out that format in a Java class will make things tidier. Here's a nice guidethat will help you get started that way.
我建议至少考虑编写类并使用 gson。我这样说的原因是因为无论哪种方式,您的应用程序逻辑都必须期望一种非常特定的格式,并且在 Java 类中写出该格式将使事情更整洁。这是一个很好的指南,可以帮助您以这种方式开始。
If you want to simply decode the JSON without serializing it into a Java class (IMHO the only way to use 'arbitrary' JSON), you'll want to use another library. Try thisone. It allows you to decode the JSON, and use it by getting values from it (as described in this question: Convert a JSON string to object in Java ME?).
如果您只想对 JSON 进行解码而不将其序列化为 Java 类(恕我直言,这是使用“任意”JSON 的唯一方法),您将需要使用另一个库。试试这个。它允许您解码 JSON,并通过从中获取值来使用它(如本问题所述:将 JSON 字符串转换为 Java ME 中的对象?)。
回答by bhlowe
There are some tools that do gson to schema mapping. You give some sample JSON responses, and the java classes to access them are created for you.
有一些工具可以进行 gson 到模式映射。您提供了一些示例 JSON 响应,并为您创建了用于访问它们的 Java 类。
回答by Stanislav Karakhanov
Gsonis a slick beast! Or at least it became so over the years that have passed since the question had been asked.
Gson是一只狡猾的野兽!或者至少自从提出这个问题以来已经过去了几年。
You can pass it an Object.classas a second parameter to the fromJson()method and it will parse your Json into a reasonable structure of LinkedTreeMaps and ArrayLists.
您可以将Object.class作为第二个参数传递给fromJson()方法,它会将您的 Json 解析为LinkedTreeMap和ArrayList的合理结构。
Object result = (new Gson()).fromJson(jsonString, Object.class)
More than that, you can really do partial parsingand leave loose ends at any level of your object structure by defining a certain field as Object!
不仅如此,通过将某个字段定义为 Object ,您真的可以进行部分解析并在对象结构的任何级别留下松散的结尾!
Gsonwill then parse Json into your structure and your field of type Object will contain the above mentioned structure of LinkedTreeMaps and ArrayLists.
然后Gson会将 Json 解析为您的结构,并且您的 Object 类型字段将包含上面提到的LinkedTreeMap和ArrayList的结构。
E.g., you may define a class
例如,您可以定义一个类
Person {
String name;
Object details;
}
(Imagine, you care mostly about the person's name but may want the details also somewhere. To log them, for instance.)
(想象一下,您主要关心此人的姓名,但也可能希望将详细信息放在某处。例如,记录它们。)
Then you can pass the following Json to the fromJson(input, Person.class)method as a first parameter
然后您可以将以下 Json作为第一个参数传递给fromJson(input, Person.class)方法
{
"name": "Carlsson",
"details": {
"address": "Stockholm",
"phones": [
"work": "233-322-233-322",
"home": "none"
]
}
}
The result will have the namefield filled with "Carlsson"string and detailsfield will contain a LinkedTreeMapwith keys "address"and "phones", etc.
结果将在name字段中填充"Carlsson"字符串,而details字段将包含一个LinkedTreeMap,其中包含键"address"和"phones"等。