具有两个具有相同SerializedName的字段的类

时间:2018-07-26 23:01:16

标签: android gson retrofit2

我的服务有问题,因为同一字段的请求和响应形式不同,因此我使用@Expose批注序列化一个序列,反序列化另一个序列:

@SerializedName("photo")
@Expose(deserialize = false)
private String imageB64;

@SerializedName("photo")
@Expose(serialize = false)
private ImageURL imageURL;

但是在响应中,我的服务正在启动异常:

Caused by: java.lang.IllegalArgumentException: class User declares multiple JSON fields named photo

我正在将Retrofit与GSON转换器配合使用。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我认为无法添加多个@SerializedName注释,因为否则您将收到所提供的错误。

但是,您可以创建一个自定义TypeAdapter来手动对对象进行序列化/反序列化,如下所示:

MyObject

public class MyObject {

  private String url;

  private int number;

  // constructor + getters + setters + custom "toString()"
  ...

}

MyObjectTypeAdapter

class MyObjectTypeAdapter extends TypeAdapter<MyObject> {

  @Override
  public void write(JsonWriter out, MyObject value) throws IOException {
    out.beginObject().name("photo").value(value.getUrl()).endObject();
  }

  @Override
  public MyObject read(JsonReader in) throws IOException {
    MyObject result = new MyObject();
    in.beginObject();
    while (in.hasNext()) {
      switch (in.nextName()) {
      case "photo":
        result.setNumber(in.nextInt());
      }
      // other fields
      ...
    }

    in.endObject();
    return result;
  }
}

您可以通过以下方式使用它:

public static void main(String[] args) {
  Gson gson = new GsonBuilder().registerTypeAdapter(MyObject.class, new MyObjectTypeAdapter()).create();

  System.out.println(gson.toJson(new MyObject("myUrl", 1)));

  MyObject deserialized = gson.fromJson("{ \"photo\": 12 }", MyObject.class);

  System.out.println(deserialized);
}

并打印(注意,我为toString()使用了自定义MyObject):

{"photo":"myUrl"}
MyObject{url='null', number=12}