提问人:Shanky 提问时间:11/2/2023 最后编辑:Oleg CherednikShanky 更新时间:11/2/2023 访问量:65
如何将字符串常量对象从 JSON 解编为 Java 对象?
How to unmarshall a string constant object from JSON to as a Java Object?
问:
我有以下JSON:
{
"code":1000,
"message":"Success",
"data":{
"results":[
{
"lineId":"C4000LG2020253739",
"lineDiagnostics":{
"C4000LG2020253739":{
"ap":{
"broadbanddsthroughput":{
"broadbandDsThroughput":[
{
"average":104830,
"std":0,
"detection":0,
"numErrorFreeSamples":1,
"sampleMaxPercentile":107673,
"latestSampleTimestamp":1698160893000,
"sampleMax":107673,
"url":"http://blah-blah.com",
"videoQuality":7,
"serviceDetection":-1,
"percentile":[
104830
],
"latestSample":104830,
"primaryIp":"205.171.3.100",
"speedTestTrafficMB":56.9910995
}
]
},
"broadbandusthroughput":{
"broadbandUsThroughput":[
{
"average":37828,
"std":0,
"numErrorFreeSamples":1,
"sampleMaxPercentile":38393,
"latestSampleTimestamp":1698160893000,
"sampleMax":38393,
"url":"http://blah-blah.com",
"serviceDetection":-1,
"percentile":[
37828
],
"latestSample":37828,
"primaryIp":"205.171.3.100",
"speedTestTrafficMB":21.8231345
}
]
}
},
"interface":{
},
"station":{
},
"multiWan":{
}
}
},
"analysisDay":20231024
}
]
}
}
在行 Diagnostics 下,我们有“C4000LG2020253739”: {...},我需要这个对象内部的内容进行进一步计算,任何人都可以告诉我如何实现这一点吗?
我正在使用 Jackson 将 JSON 值映射到 Java 类。
注意:这个特定的字符串值“C4000LG2020253739”:{...} 会随着每次微服务调用而改变(而不是 this{...} 中的内容),所以我在为此 JSON 结构创建通用 Java 类时遇到了问题。
我正在使用 Jackson 将 JSON 值映射到 Java 类:
public class Class1{
//historical speed response structure : map from json response
String code;
String message;
@JsonProperty("data")
DataSpeeds dataSpeeds;
...}
public class DataSpeeds {
@JsonProperty("results")
List<Results> results;
@JsonProperty("lineId")
String lineId;
...}
public class Results {
String lineId;
@JsonProperty("lineDiagnostics")
LineDiagnostics lineDiagnostics;
...}
public class LineDiagnostics {
@JsonProperty("ap")
Ap ap;
...}
在 LineDiagnostics 对象中,我需要从 JSON 映射“C4000LG2020253739”:{...},这怎么能做到?有什么建议吗?
答:
1赞
Oleg Cherednik
11/2/2023
#1
选项 1
至少你可以将 json 反序列化并从中检索所需的数据。Map
public static Map<String, Object> getLineDiagnosticByLineId(File file, String lineId) throws IOException {
TypeReference<HashMap<String, Object>> typeRef = new TypeReference<>() {
};
Map<String, Object> map = new ObjectMapper().readValue(file, typeRef);
Map<String, Object> data = (Map<String, Object>) map.getOrDefault("data", Map.of());
List<Object> results = (List<Object>) data.getOrDefault("results", List.of());
return results.stream()
.map(result -> (Map<String, Object>) result)
.filter(result -> lineId.equals(result.get("lineId")))
.map(result -> result.getOrDefault("lineDiagnostics", List.of()))
.map(lineDiagnostics -> (Map<String, Object>) lineDiagnostics)
.findFirst().orElse(Map.of());
}
选项 2
但我建议你建立一个模型,用它来代替.Map
简单模型可能如下所示:
@Getter
@Setter
public class DataModel {
private Integer code;
private String message;
private Data data;
@Getter
@Setter
public static class Data {
private List<Result> results;
}
@Getter
@Setter
public static class Result {
private String lineId;
private Map<String, Object> lineDiagnostics;
private Integer analysisDay;
}
}
您的业务代码如下:
public static Map<String, Object> getLineDiagnosticByLineId(File file, String lineId) throws IOException {
DataModel dataModel = new ObjectMapper().readValue(file, DataModel.class);
return dataModel.getData().getResults().stream()
.filter(result -> lineId.equals(result.getLineId()))
.map(DataModel.Result::getLineDiagnostics)
.findFirst().orElse(Map.of());
}
选项 3
最后。你可以用里面的 mup 来解决你的问题,并用注解定义 setter。Map<String, Object>
LineDiagnostics
@JsonAnySetter
@Getter
@Setter
public class DataModel {
private Integer code;
private String message;
private Data data;
@Getter
@Setter
public static class Data {
private List<Result> results;
}
@Getter
@Setter
public static class Result {
private String lineId;
private LineDiagnostics lineDiagnostics;
private Integer analysisDay;
}
@Getter
@Setter
public static class LineDiagnostics {
private Map<String, LineDiagnostic> lineDiagnostics = new HashMap<>();
@JsonAnySetter
public void setLineDiagnostic(String key, LineDiagnostic value) {
lineDiagnostics.put(key, value);
}
}
@Getter
@Setter
public static class LineDiagnostic {
private Ap ap;
@JsonProperty("interface")
private Object anInterface;
private Object station;
private Object multiWan;
}
@Getter
@Setter
public static class Ap {
@JsonProperty("broadbanddsthroughput")
private BroadbandDsThroughput broadbandDsThroughput;
@JsonProperty("broadbandusthroughput")
private BroadbandUsThroughput broadbandUsThroughput;
}
@Getter
@Setter
public static class BroadbandDsThroughput {
private List<BroadbandThroughput> broadbandDsThroughput;
}
@Getter
@Setter
public static class BroadbandUsThroughput {
private List<BroadbandThroughput> broadbandUsThroughput;
}
@Getter
@Setter
public static class BroadbandThroughput {
private Double average;
private Double std;
private Double detection;
private Integer numErrorFreeSamples;
private Integer sampleMaxPercentile;
private Long latestSampleTimestamp;
private Integer sampleMax;
private String url;
private Integer videoQuality;
private Integer serviceDetection;
private List<Integer> percentile;
private Integer latestSample;
private String primaryIp;
@JsonProperty("speedTestTrafficMB")
private Double speedTestTrafficMb;
}
}
最终结果应如下所示:
public static DataModel.LineDiagnostics getLineDiagnosticByLineId(File file, String lineId) throws IOException {
DataModel dataModel = new ObjectMapper().readValue(file, DataModel.class);
return dataModel.getData().getResults().stream()
.filter(result -> lineId.equals(result.getLineId()))
.map(DataModel.Result::getLineDiagnostics)
.findFirst().orElse(null);
}
评论
0赞
Shanky
11/3/2023
这是一个很好的答案!我一直在寻找这样的POJO。也许你错过了一个“s”:@JsonAnySetter setLineDiagnostics(...)这解决了我的问题。非常感谢!
评论
LineDiagnostics
HashMap
Result
lineDiagnostics
Map<String, LineDiagnostics>
LineDiagnostics
C4000LG2020253739
LineDiagnostics