有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

每个字段有多个GSON@SerializedName?

Gson中有没有办法将多个JSON字段映射到单个Java对象成员变量

假设我有一个Java类

public class MyClass {
    String id;
    String name;
}

我想将这个类与两个不同的服务一起使用。然而,这两种服务在返回数据的方式上有所不同

{ "id": 2341, "person": "Bob" }

。。。而且

{ "id": 5382, "user": "Mary" }

。。。分别

有没有办法将JSON字符串中的"person""user"字段映射到Java对象中的name字段

(注意:我只需要将JSON字符串转换为Java对象,而不是相反。)


共 (4) 个答案

  1. # 1 楼答案

    对于Kotlin风扇

    @SerializedName(value="name", alternate= ["person", "user"])
    
  2. # 2 楼答案

    对于KOTLIN,我在下面使用过,但不起作用

    @SerializedName(value="name", alternate= ["person", "user"])
    

    所以我编辑了它,在这里它工作得很好

    @SerializedName(value="name", alternate= arrayOf("person", "user"))
    
  3. # 4 楼答案

    不支持在Gson为字段定义多个@SerializedName注释

    原因:默认情况下,反序列化由LinkedHashMap管理,键由传入json的字段名(而不是自定义类的字段名或序列化数据名)定义,并且存在一对一映射。您可以在ReflectiveTypeAdapterFactory类的内部类Adapter<T>read(JsonReader in)方法中看到实现(反序列化如何工作)

    解决方案: 您可以编写一个自定义TypeAdapter,它处理namepersonuserjson标记,并将它们映射到自定义类的名称字段MyClass

    class MyClassTypeAdapter extends TypeAdapter<MyClass> {
    
        @Override
        public MyClass read(final JsonReader in) throws IOException {
            final MyClass myClassInstance = new MyClass();
    
            in.beginObject();
            while (in.hasNext()) {
                String jsonTag = in.nextName();
                if ("id".equals(jsonTag)) {
                    myClassInstance.id = in.nextInt();
                } else if ("name".equals(jsonTag) 
                        || "person".equals(jsonTag)
                        || "user".equals(jsonTag)) {
                    myClassInstance.name = in.nextString();
                }
            }
            in.endObject();
    
            return myClassInstance;
        }
    
        @Override
        public void write(final JsonWriter out, final MyClass myClassInstance)
                throws IOException {
            out.beginObject();
            out.name("id").value(myClassInstance.id);
            out.name("name").value(myClassInstance.name);
            out.endObject();
        }
    }
    

    测试用例:

        String jsonVal0 = "{\"id\": 5382, \"user\": \"Mary\" }";
        String jsonVal1 = "{\"id\": 2341, \"person\": \"Bob\"}";
    
        final GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(MyClass.class, new MyClassTypeAdapter());
        final Gson gson = gsonBuilder.create();
    
        MyClass myClassInstance0 = gson.fromJson(jsonVal0, MyClass.class);
        MyClass myClassInstance1 = gson.fromJson(jsonVal1, MyClass.class);
    
        System.out.println("jsonVal0 :" + gson.toJson(myClassInstance0));
        // output: jsonVal0 :{"id":5382,"name":"Mary"}
    
        System.out.println("jsonVal1 :" + gson.toJson(myClassInstance1));
        // output: jsonVal1 :{"id":2341,"name":"Bob"}
    

    Examples about TypeAdapters.

    编辑2016.04.06:正如@Mathieu Castets在其回答中所写的,现在它得到了支持。(这是这个问题的正确答案。)

    public abstract String[] alternate
    Returns: the alternative names of the field when it is deserialized
    Default: {}