使用GSON处理JSON API响应的最佳方法是什么?

时间:2016-03-28 14:43:41

标签: java json gson

我正在开发一个使用JSON与API通信的项目。这是我第一次尝试使用JSON,而且我已经远离java几年/几年了,所以请耐心等待。

以下是数据的概念:

字符串1:

[{
  "apicall1": 
     [{
      "thisField":"thisFieldData",
      "thatField":"thatFieldData",
      "anotherField":"anotherFieldData"
     }]
}]

字符串2:

[{
  "apicall2":
     [{
      "thatField":"thatFieldData",
      "someFieldsAreTheSame":"someFieldsAreTheSameData",
      "otherFieldsAreNotTheSame":"otherFieldsAreNotTheSame"
     }]
}]

从我的数据示例中可以看出,API返回一个包含所用api的JSON字符串。里面的数组包含数据。 API具有许多共同的数据字段,但除此之外它们是无关的。

编辑:有许多这些API类型需要处理。

我要做的是创建一个接受所有JSON字符串的响应类,并返回一个包含相应数据的对象。

例如:

Gson gson = new Gson(); //Custom TypeAdapter goes here if needed.
Response apicall2 = gson.fromJson(apicall2String, Response.class);

System.out.println(apicall2.thatField);                //Prints thatFieldData 
System.out.println(apicall2.someFieldsAreTheSame);     //Prints someFieldsAreTheSameData
System.out.println(apicall2.otherFieldsAreNotTheSame); //Prints otherFieldsAreNotTheSameData

这是我迷失的地方。这是我到目前为止所拥有的。我想我需要在这里使用TypeAdapter,但我们无法想出如何将其应用到我的案例中。

 public class Response {  //Change to TypeAdapter possibly?
 }
 public class apicall1 {
      String thisField;
      String thatField;
      String anotherField;
 }
 public class apicall2 {
      String thatField;
      String someFieldsAreTheSame;
      String otherFieldsAreNotTheSame;
 }

2 个答案:

答案 0 :(得分:0)

您可以使用Gson的TypeToken类将json反序列化为对象。以下是一个例子:

<强> JSON:

[{  "apicall1": 
     [{
      "thisField":"thisFieldData",
      "thatField":"thatFieldData",
      "anotherField":"anotherFieldData"
     }]
}]

<强>型号:

class Response{

    private List<Result> apicall1;

    class Result{
        private String thisField;
        private String thatField;
        private String anotherField;
        public String getThisField() {
            return thisField;
        }
        public void setThisField(String thisField) {
            this.thisField = thisField;
        }
        public String getThatField() {
            return thatField;
        }
        public void setThatField(String thatField) {
            this.thatField = thatField;
        }
        public String getAnotherField() {
            return anotherField;
        }
        public void setAnotherField(String anotherField) {
            this.anotherField = anotherField;
        }
    }

    public List<Result> getApicall1() {
        return apicall1;
    }

    public void setApicall1(List<Result> apicall1) {
        this.apicall1 = apicall1;
    }
}

<强>转换器:

public static void main(String[] args) {
    String response = "[{  \"apicall1\":      [{      \"thisField\":\"thisFieldData\",      \"thatField\":\"thatFieldData\",      \"anotherField\":\"anotherFieldData\"     }]}]";
    Gson gson = new Gson();
    List<Response> responses = gson.fromJson(response, new TypeToken<List<Response>>(){}.getType());
    System.out.println(responses.get(0).getApicall1().get(0).getThisField());
}

答案 1 :(得分:0)

我不知道你是否想要在一个类中使用两个适配器。可能不是最好的OOP设计。

要实现这一目标,你需要做同样的事情:

public class DoublyTypeAdapter implements JsonDeserializer<ApiCallTypeParent>
{
    Gson gson = new Gson();

    @Override
    public ApiCallTypeParent deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext)
            throws JsonParseException {
        JsonObject json = jsonElement.getAsJsonObject();

        ApiCallTypeParent desrializeIntoMe;
        // Detect which type to implement
        if(apiTypeOne(type) {
              desrializeIntoMe = new TypeOne();
        } else {
              desrializeIntoMe = new TypeTwo();
        }

        for (Map.Entry<String, JsonElement> entry : json.entrySet())
        {
            switch(entry.getKey()){
            case "thisField":
                desrializeIntoMe.setThisField(entry.getValue().getAsString());
                break;
            ......    
            default: // We don't care
                break;
            }
        }

        return desrializeIntoMe ;
      }
}