0

My json response

[
     [
        {
          "header_id": 1,
          "name" : "Tom",
          "group" : "A"
        },
        {
          "header_id": 2,
          "name" : "Marry",
          "group" : "B"
         }
    ],

    [
         {
             "object_id" : 1,
             "SerialNo" : 123456
         },
         {
             "object_id" : 2,
             "SerialNo" : 89545
         }
     ],

     [
        {
           "workflow_id" : 1,
           "StatusName" : "start"
         },
         {
            "workflow_id" : 2,
            "StatusName" : "end"
          }

    ]
]

Header.class

public class Header{
    @SerializedName("header_id")
    private int HeaderID;
    @SerializedName("name")
    private String name;
    @SerializedName("group")
    private String group;
}

ObjectWork.class

public class ObjectWork {
    @SerializedName("object_id")
    private int ObjectID;
    @SerializedName("SerialNo")
    private int SerialNo;
}

WorkFlow.class

public class WorkFlow{
    @SerializedName("workflow_id")
    private int WorkflowID;
    @SerializedName("StatusName")
     private String statusName;
}

In json array , there are three type json object. How will I design pojo and custom JsonDeserializer in retrofit2. Now I use gson to parse this. I don't know to design class for support this json and deserializer it to pojo model.

Thankyou

0

2 Answers 2

2

Introduce a common wrapper to let Gson recognize your since Gson prohibits java.lang.Object overriding (note the recommended fieldNamesCaseThatIsAlwaysCamelCase):

abstract class AbstractCommon {
}
final class Header
        extends AbstractCommon {

    @SerializedName("header_id")
    final int headerId = Integer.valueOf(0);

    @SerializedName("name")
    final String name = null;

    @SerializedName("group")
    final String group = null;

    @Override
    public String toString() {
        return headerId + ": " + name;
    }

}
final class ObjectWork
        extends AbstractCommon {

    @SerializedName("object_id")
    final int objectId = Integer.valueOf(0);

    @SerializedName("SerialNo")
    final int serialNo = Integer.valueOf(0);

    @Override
    public String toString() {
        return objectId + ": " + serialNo;
    }

}
final class WorkFlow
        extends AbstractCommon {

    @SerializedName("workflow_id")
    final int workflowId = Integer.valueOf(0);

    @SerializedName("StatusName")
    final String statusName = null;

    @Override
    public String toString() {
        return workflowId + ": " + statusName;
    }

}

Now introduce a JsonDeserializer that would try to recognize actual type:

private static final Gson gson = new GsonBuilder()
        .registerTypeAdapter(AbstractCommon.class, (JsonDeserializer<AbstractCommon>) (jsonElement, type, context) -> {
            final JsonObject jsonObject = jsonElement.getAsJsonObject();
            if ( jsonObject.has("header_id") ) {
                return context.deserialize(jsonElement, Header.class);
            }
            if ( jsonObject.has("object_id") ) {
                return context.deserialize(jsonElement, ObjectWork.class);
            }
            if ( jsonObject.has("workflow_id") ) {
                return context.deserialize(jsonElement, WorkFlow.class);
            }
            throw new IllegalArgumentException("Cannot recognize: " + jsonElement);
        })
        .create();

Now you can easily do:

private static final Type commonsType = new TypeToken<List<List<AbstractCommon>>>() {
}.getType();

public static void main(final String... args)
        throws IOException {
    try ( final JsonReader jsonReader = getPackageResourceJsonReader(Q44034331.class, "arrays.json") ) {
        final List<List<AbstractCommon>> commons = gson.fromJson(jsonReader, commonsType);
        commons.stream()
                .flatMap(Collection::stream)
                .forEach(abstractCommon -> System.out.println(abstractCommon.getClass().getSimpleName() + ": " + abstractCommon));
    }
}

Output:

Header: 1: Tom
Header: 2: Marry
ObjectWork: 1: 123456
ObjectWork: 2: 89545
WorkFlow: 1: start
WorkFlow: 2: end

Frankly speaking I find your JSON a bit weird (assuming the subarrays elements really look related to each other but deconstructed): it's somewhat like an inside-out by structure. If you can control the JSON format, I really commend you to redesign it. If it's not under your control, it looks like you'd need something like this (that's also possible with Gson type adapters):

final class Wrapper {

    final Header header;
    final ObjectWork objectWork;
    final WorkFlow workFlow;

    Wrapper(final Header header, final ObjectWork objectWork, final WorkFlow workFlow) {
        this.header = header;
        this.objectWork = objectWork;
        this.workFlow = workFlow;
    }

}
private static Collection<Wrapper> combine(final List<List<AbstractCommon>> commons) {
    @SuppressWarnings({ "unchecked", "rawtypes" })
    final List<Header> headers = (List) commons.get(0);
    @SuppressWarnings({ "unchecked", "rawtypes" })
    final List<ObjectWork> objectWorks = (List) commons.get(1);
    @SuppressWarnings({ "unchecked", "rawtypes" })
    final List<WorkFlow> workFlows = (List) commons.get(2);
    final Iterator<Header> headerIterator = headers.iterator();
    final Iterator<ObjectWork> objectWorkIterator = objectWorks.iterator();
    final Iterator<WorkFlow> workFlowIterator = workFlows.iterator();
    final Collection<Wrapper> wrappers = new ArrayList<>();
    while ( headerIterator.hasNext() && objectWorkIterator.hasNext() && workFlowIterator.hasNext() ) {
        final Header header = headerIterator.next();
        final ObjectWork objectWork = objectWorkIterator.next();
        final WorkFlow workFlow = workFlowIterator.next();
        final Wrapper wrapper = new Wrapper(header, objectWork, workFlow);
        wrappers.add(wrapper);
    }
    return wrappers;
}
combine(commons)
        .forEach(wrapper -> System.out.println(wrapper.header + ", " + wrapper.objectWork + ", " + wrapper.workFlow));

Output:

1: Tom, 1: 123456, 1: start
2: Marry, 2: 89545, 2: end

Sign up to request clarification or add additional context in comments.

Comments

0

Follow link to make a pojo directly from JSON:http://www.jsonschema2pojo.org/

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Example {

@SerializedName("header_id")
@Expose
private Integer headerId;
@SerializedName("name")
@Expose
private String name;
@SerializedName("group")
@Expose
private String group;

public Integer getHeaderId() {
return headerId;
}

public void setHeaderId(Integer headerId) {
this.headerId = headerId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getGroup() {
return group;
}

public void setGroup(String group) {
this.group = group;
}

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.