Reputation: 68
{
"response": {
"data": {
"333": [
{
"id": "69238",
"code": "545"
},
{
"id": "69239",
"code": "545",
"marked": "123"
}
],
"544": [
{
"id": "69906",
"code": "544",
"marked": "123"
},
{
"id": "69907",
"code": "544"
}
],
"890": [
{
"id": "69238",
"code": "545",
"marked": "123"
},
{
"id": "69239",
"code": "545"
}
]
}
}
}
I have this JSON
data as a response and try to mapping. Unfortunately I can't.
The first reason is index of objects are changeable. For example one index 890 and other one is 544.
The second reason is count of items in object are different.
When I try to create java classes with www.jsonschema2pojo.org. I get lots of classes with underscore + integer. For example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
public class _544 {
@SerializedName("id")
@Expose
private String id;
@SerializedName("code")
@Expose
private String code;
@SerializedName("marked")
@Expose
private String marked;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMarked() {
return marked;
}
public void setMarked(String marked) {
this.marked = marked;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(id).append(code).append(marked).toHashCode();
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if ((other instanceof _544) == false) {
return false;
}
_544 rhs = ((_544) other);
return new EqualsBuilder().append(id, rhs.id).append(code, rhs.code).append(marked, rhs.marked).isEquals();
}
}
and the other one is like this
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
public class _890 {
@SerializedName("id")
@Expose
private String id;
@SerializedName("code")
@Expose
private String code;
@SerializedName("marked")
@Expose
private String marked;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMarked() {
return marked;
}
public void setMarked(String marked) {
this.marked = marked;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(id).append(code).append(marked).toHashCode();
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if ((other instanceof _890) == false) {
return false;
}
_890 rhs = ((_890) other);
return new EqualsBuilder().append(id, rhs.id).append(code, rhs.code).append(marked, rhs.marked).isEquals();
}
}
The numbers 544 or 890 etc. are dynamic
So how can I do mapping with this dynamic indexed data with Java?
Thanks for help.
Upvotes: 1
Views: 1577
Reputation: 1513
You can use a custom deserializer. The below example is using Gson, but the same thing can be done with Jackson.
class CustomDeserializer implements JsonDeserializer<Response> {
@Override
public Response deserialize(JsonElement jsonElement, Type typeOfElement, JsonDeserializationContext context) throws JsonParseException {
JsonObject data = jsonElement.getAsJsonObject().get("response").getAsJsonObject().get("data").getAsJsonObject();
Type listType = new TypeToken<List<Data>>() {}.getType();
Map<String, List<Data>> dataMap = new HashMap<String, List<Data>>();
for (Map.Entry<String, JsonElement> entry : data.entrySet()) {
List<Data> dataList = context.deserialize(entry.getValue(), listType);
dataMap.put(entry.getKey(), dataList);
}
return new Response(dataMap);
}
}
In the main class:
String json = "...";
Gson gson = new GsonBuilder().registerTypeAdapter(Response.class, new CustomDeserializer()).create();
System.out.println(gson.fromJson(json, Response.class));
Class for the response:
class Response {
private Map<String, List<Data>> data;
public Response(Map<String, List<Data>> data) {
this.data = data;
}
}
Class for each data object:
class Data {
private String id;
private String code;
private String mark;
}
The response here will have a map of each data entry and a list of its values. (ex: 333 -> list of Data objects), but you can change the deserializer to have the key (333) to be one of the variables of the Data object and assign it in the for loop.
Upvotes: 1