使用gson处理jsonapi响应的最佳方法是什么?

umuewwlo  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(254)

我正在做一个使用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;
 }
eqfvzcg8

eqfvzcg81#

你可以用格森的 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());
}
sirbozc5

sirbozc52#

我不知道你是否想在一个类中同时使用两个适配器。可能不是最好的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 ;
      }
}

相关问题