Java 如何使用 GSON 迭代 JSON 数组并从中提取每个 JSON 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24257631/
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 iterate JSON Array and extract each JSON Object from it using GSON?
提问by john
Below is my JSON String which I am getting back by calling from a service API. I have shorten it down by having only three reportRecords
for the understanding purpose. In general, it might have ~500 reportRecords
下面是我通过从服务 API 调用返回的 JSON 字符串。reportRecords
为了理解目的,我已经缩短了它只有三个。一般来说,它可能有~500reportRecords
{
???"aggRecords": {
??????"reportRecords": [
?????????{
????????????"min": 0,
????????????"max": 12,
????????????"avg": 0.3699187,
????????????"count": 246,
????????????"sumSq": 571,
????????????"stddev": 1.4779372,
????????????"median": 0,
????????????"percentileMap": {
???????????????"95": 4
????????????},
????????????"metricName": "TransactionDuration",
????????????"dimensions": {
???????????????"env": "dev",
???????????????"pool": "titan",
???????????????"Name": "PostProcessing",
???????????????"Type": "PostProcessing"
????????????},
????????????"value": 91
?????????},
?????????{
????????????"min": 0,
????????????"max": 23,
????????????"avg": 2.3991289E-4,
????????????"count": 1463031,
????????????"sumSq": 3071,
????????????"stddev": 0.045814946,
????????????"median": 0,
????????????"percentileMap": {
???????????????"95": 0
????????????},
????????????"metricName": "TransactionDuration",
????????????"dimensions": {
???????????????"env": "dev",
???????????????"pool": "titan",
???????????????"Name": "ResourceContext",
???????????????"Type": "ResourceContext"
????????????},
????????????"value": 351
?????????},
?????????{
????????????"min": 0,
????????????"max": 1209,
????????????"avg": 1.9203402,
????????????"count": 7344636,
????????????"sumSq": 71832774,
????????????"stddev": 2.4683187,
????????????"median": 2,
????????????"percentileMap": {
???????????????"95": 4
????????????},
????????????"metricName": "TransactionDuration",
????????????"dimensions": {
???????????????"env": "dev",
???????????????"pool": "titan",
???????????????"Name": "Client::Sync",
???????????????"Type": "Client::Sync"
????????????},
????????????"value": 14104200
?????????}
??????]
???},
???"minRecordsMap": {}
}
Now From the above JSON response, I need to extract reportRecords
whose Name
is Client::Sync
. Meaning, I need to extract below reportRecords
from the above JSON response only.
现在从上面的 JSON 响应中,我需要提取reportRecords
who Name
is Client::Sync
。意思是,我只需reportRecords
要从上面的 JSON 响应中提取以下内容。
?????????{
????????????"min": 0,
????????????"max": 1209,
????????????"avg": 1.9203402,
????????????"count": 7344636,
????????????"sumSq": 71832774,
????????????"stddev": 2.4683187,
????????????"median": 2,
????????????"percentileMap": {
???????????????"95": 4
????????????},
????????????"metricName": "TransactionDuration",
????????????"dimensions": {
???????????????"env": "dev",
???????????????"pool": "titan",
???????????????"Name": "Client::Sync",
???????????????"Type": "Client::Sync"
????????????},
????????????"value": 14104200
?????????}
And now I need to parse the above reportRecords
for Client::Sync
to below object -
现在我需要将上面的内容解析reportRecords
为Client::Sync
下面的对象 -
public class DataMetrics {
private String pool;
private String name;
private String type;
private String env;
private String metricName;
private String percentile;
private String median;
private String stdDev;
private String sumSq;
private String count;
private String avg;
private String max;
private String min;
// getters and setters here
}
Above variable, maps like this -
上面的变量,映射是这样的 -
pool is titan
name is Client::Sync
type is Client::Sync
env is dev
metricNname is TransactionDuration
95th percentile is 4
median is 2
stdDev is 2.4683187
sumSq is 71832774
count is 7344636
avg is 1.9203402
max is 1209
min is 0
I am using GSON library here and below is what I have tried so far -
我在这里使用 GSON 库,下面是我迄今为止尝试过的 -
private static RestTemplate restTemplate = new RestTemplate();
public static void main(String[] args) {
String jsonLine = restTemplate.getForObject("some_url", String.class);
System.out.println(jsonLine); // here jsonLine will give me above big JSON String
JsonElement jelement = new JsonParser().parse(jsonLine);
JsonObject jobject = jelement.getAsJsonObject();
jobject = jobject.getAsJsonObject("aggRecords");
JsonArray jarray = jobject.getAsJsonArray("reportRecords");
// now how do I iterate JsonArray and get each JSON object
// and then check "name" property of each object, if "Client::Sync" found, read that object for all properties
// and set it using setters.
}
Now I am not able to understand how do I iterate JsonArray and extract each JSON object from it?
现在我无法理解如何迭代 JsonArray 并从中提取每个 JSON 对象?
采纳答案by vach
So you have the JsonArray object with your records, here's what you do to get your functional objects:
所以你有你的记录的 JsonArray 对象,这是你获取功能对象的方法:
Type type = new TypeToken<List<DataMetrics>>() {}.getType();
List<DataMetrics> records = gson.fromJson(jsonArrayThatYouHave, type);
Then you iterate through you objects and filter the ones you need. In java 8 you can do this:
然后你遍历你的对象并过滤你需要的对象。在 Java 8 中,你可以这样做:
List<DataMetrics> result = records.stream().filter(record -> record.name.equals("Client::Sync")).collect(toList());
This approach is converting all objects and iterating after, if exactly this part of code is performance critical, you can still iterate through json and convert only necessary objects (but i doubt that this will be actually faster than described above).
这种方法是转换所有对象并在之后进行迭代,如果这部分代码对性能至关重要,您仍然可以遍历 json 并仅转换必要的对象(但我怀疑这实际上会比上述更快)。
Anyway this is more maintainable and understandable code.
无论如何,这是更易于维护和理解的代码。
UPDATE:
更新:
the same for java 7 will be:
java 7的相同将是:
List<DataMetrics> result = new LinkedList<>();
for(DataMetrics record : records){
if(record.name.equals("Client::Sync")){
result.add(record);
}
}
回答by U_D
You may want to parse all the objects, and then filter the ones you're interested in.
您可能希望解析所有对象,然后过滤您感兴趣的对象。
After you've obtained jArray, try:
获得 jArray 后,请尝试:
//get json array from json string
JsonArray jarray = jobject.getAsJsonArray("reportRecords");
//get a list of reportRecords using Gson
Gson mGson = new Gson();
Type listType = new TypeToken<List<DataMetrics>>(){}.getType();
List<DataMetrics> dataMetricsList = mGson.fromJson(reportRecordsJsonArray, listType);
//Filter only the ones with a specific name
List<DataMetrics> dataMetricsFilteredList = dataMetricsList.stream().filter(dataMetric -> dateMetric.getName.equals("Client::Sync"));
回答by erdem karayer
i didn't try it but it may work.
我没有尝试,但它可能工作。
public void getFromJson(JSONObject json)
{
JSONArray jarray = (JSONArray) json.get("reportRecords");
List<DataMetrics> myList = new ArrayList();
for(int i = 0; i < jarray.size(); i++)
{
myList.add((DataMetrics) getClassFromJsonObject((JSONObject) jarray.get(i),
DataMetrics.class));
}
}
//// public Object getClassFromJsonObject(JSONObject json, Class myClass){
//// 公共对象 getClassFromJsonObject(JSONObject json, Class myClass){
Object object = new Object();
ObjectMapper obj = JSONMapperFactory.createMapper();
obj.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
object = obj.readValue(json.toString(), myClass);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return myClass.cast(object);
}
回答by vach
Or if you want to iterate json and parse only required ones heres what you can do:
或者,如果您想迭代 json 并仅解析所需的内容,您可以执行以下操作:
Type type = new TypeToken<List<DataMetrics>>() {}.getType();
for(JsonElement elem : jsonArrayThatYouHave) {
if (elem.getAsJsonObject().get("name").getAsString().equals("Client::Sync")) {
result.add(gson.fromJson(elem, type));
}
}
but I dont think this is actually faster than the first one because in both cases you are converting json to java functional object with parser and getting JsonArray or anything else. Taking into consideration the fact that both are Googles libs, i assume that parsing from JsonObject to some specific type with gson is way faster than from String (raw json) to the same specific type...
但我不认为这实际上比第一个更快,因为在这两种情况下,您都使用解析器将 json 转换为 java 功能对象并获取 JsonArray 或其他任何东西。考虑到两者都是 Google 的库这一事实,我认为从 JsonObject 解析为使用 gson 的某些特定类型比从 String(原始 json)解析为相同的特定类型要快得多......