Java 如何使用GSON迭代JSON数组并从中提取每个JSON对象?
下面是我从服务API调用得到的JSON字符串。为了便于理解,我将其缩短为只有三个Java 如何使用GSON迭代JSON数组并从中提取每个JSON对象?,java,json,gson,arrays,jsonobject,Java,Json,Gson,Arrays,Jsonobject,下面是我从服务API调用得到的JSON字符串。为了便于理解,我将其缩短为只有三个reportRecords。一般来说,它可能有约500条reportRecords { "aggRecords": { "reportRecords": [ { "min": 0, "max": 12, "avg": 0.3699187, "count": 246,
reportRecords
。一般来说,它可能有约500条reportRecords
{
"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": {}
}
现在,从上面的JSON响应中,我需要提取reportRecords
,它的Name
是Client::Sync
。也就是说,我只需要从上面的JSON响应中提取下面的reportRecords
{
"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
}
现在我需要为Client::Sync
将上面的reportRecords
解析到下面的对象-
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
}
上面的变量,映射如下-
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
我在这里使用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.
}
现在我无法理解如何迭代JsonArray并从中提取每个JSON对象?您可能需要解析所有对象,然后过滤您感兴趣的对象 获得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"));
//从json字符串获取json数组
JsonArray jarray=jobject.getAsJsonArray(“报告记录”);
//使用Gson获取reportRecords列表
Gson mGson=新的Gson();
类型listType=newTypeToken(){}.getType();
List dataMetricsList=mGson.fromJson(reportRecordsJShonaray,listType);
//仅筛选具有特定名称的
List dataMetricsFilteredList=dataMetricsList.stream().filter(dataMetric->dateMetric.getName.equals(“Client::Sync”);
我没有试过,但它可能有用
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));
}
}
因此,记录中有JsonArray对象,下面是获取函数对象的方法:
Type type = new TypeToken<List<DataMetrics>>() {}.getType();
List<DataMetrics> records = gson.fromJson(jsonArrayThatYouHave, type);
Type Type=new-TypeToken(){}.getType();
List records=gson.fromJson(jsonArrayThatYouHave,type);
然后遍历对象并过滤所需的对象。
在java 8中,可以执行以下操作:
List<DataMetrics> result = records.stream().filter(record -> record.name.equals("Client::Sync")).collect(toList());
List result=records.stream().filter(record->record.name.equals(“Client::Sync”)).collect(toList());
这种方法是转换所有对象并在之后进行迭代,如果这部分代码确实是性能关键的,那么您仍然可以通过json进行迭代,并仅转换必要的对象(但我怀疑这实际上会比上面描述的更快)
无论如何,这是更易于维护和理解的代码
更新:
java 7的相同功能将是:
List<DataMetrics> result = new LinkedList<>();
for(DataMetrics record : records){
if(record.name.equals("Client::Sync")){
result.add(record);
}
}
List result=newlinkedlist();
对于(DataMetrics记录:记录){
if(record.name.equals(“Client::Sync”)){
结果.添加(记录);
}
}
或者,如果您想迭代json并只解析所需的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));
}
}
Type Type=new-TypeToken(){}.getType();
for(JsonElement元素:jsonArrayThatYouHave){
if(elem.getAsJsonObject().get(“name”).getAsString().equals(“Client::Sync”)){
add(gson.fromJson(elem,type));
}
}
但我认为这实际上并不比第一个更快,因为在这两种情况下,您都是使用解析器将json转换为java函数对象,并获得JsonArray或其他任何东西。考虑到两者都是Google LIB,我假设使用gson从JsonObject解析到某个特定类型比从字符串(原始json)解析到同一特定类型要快得多…@hexin我正在使用gson,我猜上面的示例不使用gson。谢谢Vach。在Java7中我将如何做到这一点?我现在正在使用Java7。谢谢你的帮助。我试过了,但不知怎么的,大多数字段都是空的,比如百分位、名称、类型、最小值等,但有些字段有数据。您是否看到任何错误?您只需要与json中相同的类属性名称(如果不想更改,请使用@Qualifier注释指定它)
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));
}
}