简体   繁体   中英

Parse JSON using Gson (or alternative for java)

I've worked with Gson for quite some time but this one has me scratching my head. Here is a typical json response I am getting back from a REST call. Notice that there are several nested references that are of the same type. Any idea how I can solve this with Gson (or another java library) without having to do string manipulation?

I've tried using annotations to declare the same name but end up with:

@SerializedName("Context")

declares multiple JSON fields named Context

"response": {
    "Context": {
        "Context": {
            "ttContext": [
                {
                    "taskId": "",
                    "name": "GUID",
                    "value": "abc123"
                }
            ]
        }
    },
    "Data": {
        "Data": {
            "ttData": [
                {
                    "name": "Bob Brown",
                    "address": "101 Anywhere St",
                    "city": "Spruce Pine",
                    "state": "AL",
                    "zipcd" : 12345
                }
            ]
        }
    }
}

They're not the same type if you look at them as a JSON structure. They can be represented with a bunch of (almost nonsense) classes like the ones below.

public class Response()
{
    public Response(){}

    private ExternalContext Context;
    private ExternalData Data;
}

public class ExternalContext
{
    public ExternalContext(){}

    private IntermediateContext Context;

}

public class IntermediateContext
{
    public IntermediateContext(){}

    private Context ttContext;
}

public class Context
{
    public Context(){}

    private String taskId;
    private String name;
    private String value;
}

// the same idea can be applied to ExternalData

You just need to use GSON to deserialize Response.

What I did below is to create a Java class that can contain itself via a constructor.

I actually created a JUnit test. I also put all of the getters/setters so it may be unnecessarily too long for this forum. My apologies.

import com.google.gson.Gson;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class TestThrowaway {

public class Container {
    Response response;

    public Container() {
    }

    public Response getResponse() {
        return response;
    }

    public void setResponse(Response response) {
        this.response = response;
    }
}

public class Response {
    private Context Context;
    private Data Data;

    public Response() {
    }

    public TestThrowaway.Context getContext() {
        return Context;
    }

    public void setContext(TestThrowaway.Context context) {
        Context = context;
    }

    public TestThrowaway.Data getData() {
        return Data;
    }

    public void setData(TestThrowaway.Data data) {
        Data = data;
    }
}

public class Context {
    private Context Context;
    private List<TtContext> ttContext;

    public Context() {}
    public Context(Context context) {
        this.Context = context;
    }

    public TestThrowaway.Context getContext() {
        return Context;
    }

    public void setContext(TestThrowaway.Context context) {
        Context = context;
    }

    public List<TtContext> getTtContext() {
        return ttContext;
    }

    public void setTtContext(List<TtContext> ttContext) {
        this.ttContext = ttContext;
    }
}

public class TtContext {
    private String taskId;
    private String name;
    private String value;

    public TtContext(String taskId, String name, String value) {
        this.taskId = taskId;
        this.name = name;
        this.value = value;
    }

    public TtContext() {
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getName() {
        return name;
    }

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

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

public class Data {
    private Data Data;
    private List<TtData> ttData;

    public Data() {
    }

    public Data(TestThrowaway.Data data) {
        Data = data;
    }

    public TestThrowaway.Data getData() {
        return Data;
    }

    public void setData(TestThrowaway.Data data) {
        Data = data;
    }

    public void setTtData(List<TtData> ttData) {
        this.ttData = ttData;
    }

}

public class TtData {
    private String name;
    private String address;
    private String city;
    private String state;
    private Integer zipcd;

    public TtData() {
    }

    public TtData(String name, String address, String city, String state, Integer zipcd) {
        this.name = name;
        this.address = address;
        this.city = city;
        this.state = state;
        this.zipcd = zipcd;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Integer getZipcd() {
        return zipcd;
    }

    public void setZipcd(Integer zipcd) {
        this.zipcd = zipcd;
    }
}

@Test
public void test() {
    // Create inner Context object
    Context innerContext = new Context();

    // Create your ttContext list. For ease, I created a constructor that takes in all of your values
    List<TtContext> ttContexts = new ArrayList<>();
    ttContexts.add(new TtContext("", "GUID", "abc123"));

    // Add your list to your inner Context
    innerContext.setTtContext(ttContexts);

    // Create a new Context object that takes in a Context object, the inner Context object
    Context outsideContext = new Context(innerContext);

    // Create inner Data object
    Data innerData = new Data();

    // Create your ttData list.
    List<TtData> ttDatas = new ArrayList<>();
    ttDatas.add(new TtData("Bob Brown", "101 Anywhere St", "Spruce Pine", "AL", 12345));

    // Add your list to your inner Data
    innerData.setTtData(ttDatas);

    // Create a new Data object that takes in a Data object, the inner Data object
    Data outsideData = new Data(innerData);

    // Create a Response object that will set both the outsideContext object and the outsideData object
    Response response = new Response();
    response.setContext(outsideContext);
    response.setData(outsideData);

    // If you leave like this and run Gson, you won't have the wrapping "response" object.  
    // I like to create a Container object that takes in the Response object so I can create a variable 
    // called response and Gson does everything for me.  

    Container container = new Container();
    container.setResponse(response);

    // Instantiate Gson and run the method toJson.
    Gson gson = new Gson();
    String s = gson.toJson(container);
    System.out.println(s);
}
}

The result from the test is:

{
  "response": {
    "Context": {
      "Context": {
        "ttContext": [
          {
            "taskId": "",
            "name": "GUID",
            "value": "abc123"
          }
        ]
      }
    },
    "Data": {
      "Data": {
        "ttData": [
          {
            "name": "Bob Brown",
            "address": "101 Anywhere St",
            "city": "Spruce Pine",
            "state": "AL",
            "zipcd": 12345
          }
        ]
      }
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM