Getting values by a previously unknown key in JSON (Java Gson)
I support Java test code for processing requests from the server using the Gson library. Everything was fine, until recently. Input data: there is an array of 28000 + rows, I will give the JSON part with the part of interest:
{
"status": {
"code": code,
"message": "message"
},
"data": {
"datas": [
{
"id": idHere,
"date_gmt": "2020-08-04T07:01:47",
"title": "title1",
"status": "publish",
"data_category": [
263,
495,
492,
68
],
"is-bonus-data": false,
"data-poster": "link here",
"data-preview-sprite": "link here",
"sprite": "link here",
"data-links": {
"3D 180 01_trailer": "link here",
"3D 180 02_trailer": "link here",
"3D 180 03_trailer": "link here",
"3D 180 04_trailer": "link here",
"3D 180 05_trailer": "link here"
},
"data-positions": [
"data-positions1",
"data-positions2"
],
...
}
This JSON is described in the class, and when it is received, everything is normally parsed, but ...
Recently, the "data-links" field began to receive objects with keys that differ from the "standard" ones - "3D 180 01_trailer_001", " 3D 360 03_trailer" etc. At first, it was decided to add these keys as a class field, and actually parse them as well, but the data-links class itself has already swollen to an incredible size.
A class that describes
public class DataLinks {
@SerializedName("3D 180 01_trailer")
@Expose
private String _3D18001Trailer;
@SerializedName("3D 180 02_trailer")
@Expose
private String _3D18002Trailer;
@SerializedName("3D 180 03_trailer")
@Expose
private String _3D1803KTrailer;
@SerializedName("3D 180 04_trailer")
@Expose
private String _3D1804KTrailer;
@SerializedName("3D 180 05_trailer")
@Expose
private String _3D18005Trailer;
}
Question: how to ensure that tests "pull out" values by keys that are unknown in advance?
I looked at google answers, very different, where people give examples, the most suitable one was here: How to parse a dynamic JSON key in a nested JSON result, but the code starts spitting excepshenami when trying to adapt.
1 answers
You can use java.util.Map
:
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
@Data
static class Test {
@SerializedName("data-links")
private Map<String, String> dataLinks;
}
public static void main(String[] args) {
String json =
"{" +
"\"data-links\": {" +
"\"3D 180 01_trailer\": \"link here\"," +
"\"3D 180 02_trailer\": \"link here\"," +
"\"3D 180 03_trailer\": \"link here\"," +
"\"3D 180 04_trailer\": \"link here\"," +
"\"3D 180 05_trailer\": \"link here\"" +
"}" +
"}";
Test test = new Gson().fromJson(json, Test.class);
System.out.println(
test.dataLinks.entrySet().stream()
.map(e -> e.getKey() + ": " + e.getValue())
.collect(Collectors.joining("\n")));
}
}
Result:
3D 180 01_trailer: link here
3D 180 02_trailer: link here
3D 180 03_trailer: link here
3D 180 04_trailer: link here
3D 180 05_trailer: link here