【问题标题】:Class with two fields with same SerializedName具有两个具有相同 SerializedName 的字段的类
【发布时间】:2018-07-26 23:01:16
【问题描述】:

我的服务有问题,因为同一字段在请求和响应中的形式不同,因此我使用@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

我正在使用带有 GSON 转换器的 Retrofit。

感谢您的帮助!

【问题讨论】:

    标签: android gson retrofit2


    【解决方案1】:

    我认为不可能添加多个 @SerializedName 注释,否则你会得到你提供的错误。

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

    我的对象

    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}
    

    【讨论】:

    【解决方案2】:
    @SerializedName("photo")
    private Object imageUrl;
    
    
    public String getImageB64()
    {
        return (String) this.imageUrl
    }
    
    public void setImageB64( String image )
    {
        this.imageUrl = image
    }
    
    public ImageURL getimageURL()
    {
        return (ImageURL) this.imageUrl
    }
    
    public void setimageURL( ImageURL imageUrl )
    {
        this.imageUrl = imageUrl
    }
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2017-08-20
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2020-05-19
    相关资源
    最近更新 更多