Java 每个字段有多个 GSON @SerializedName?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25707728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple GSON @SerializedName per field?
提问by Gus
Is there any way in Gson to map multiple JSON fields to a single Java object member variable?
Gson 有没有办法将多个 JSON 字段映射到单个 Java 对象成员变量?
Let's say I have a Java class...
假设我有一个 Java 类...
public class MyClass {
String id;
String name;
}
I want to use this single class with two different services. However, these two services differ in how they return their data...
我想将这个单一的类与两种不同的服务一起使用。但是,这两种服务在返回数据的方式上有所不同......
{ "id": 2341, "person": "Bob" }
... and ...
... 和 ...
{ "id": 5382, "user": "Mary" }
... respectively.
... 分别。
Is there any way to map both the "person"
and "user"
fields in the JSON string to the name
field in the Java object?
有没有办法将 JSON 字符串中的"person"
和"user"
字段映射到name
Java 对象中的字段?
(Note: I only ever need to convert from JSON string to Java object - never the other way around.)
(注意:我只需要从 JSON 字符串转换为 Java 对象 - 从不反过来。)
回答by Devrim
It is not supported to define multiple @SerializedName
annotations to a field at Gson.
@SerializedName
Gson不支持为一个字段定义多个注释。
Reason:By default Deserialization is managed with a LinkedHashMap and the keys are defined by incoming json's field names (not the custom class's field names or the serializedNames) and there is a one to one mapping. You can see the implementation(how deserialization works) at ReflectiveTypeAdapterFactory
class's inner class Adapter<T>
's read(JsonReader in)
method.
原因:默认情况下,反序列化由 LinkedHashMap 管理,键由传入的 json 字段名称(不是自定义类的字段名称或序列化名称)定义,并且存在一对一映射。您可以在ReflectiveTypeAdapterFactory
类的内部类Adapter<T>
的read(JsonReader in)
方法中看到实现(反序列化是如何工作的)。
Solution:You can write a custom TypeAdapterwhich handles name
, person
and user
json tags and maps them to name field of your custom class MyClass
:
解决办法:你可以写一个自定义的TypeAdapter负责处理name
,person
而user
JSON标签,并将它们映射到您的自定义类的名称字段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();
}
}
Test case:
测试用例:
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"}
Edit 2016.04.06 :As @Mathieu Castets has written at his answer, it is supported now. (That is the correct answer for this question.)
编辑 2016.04.06 :正如@Mathieu Castets 在他的回答中所写的那样,现在支持它。(这是这个问题的正确答案。)
public abstract String[] alternate
Returns: the alternative names of the field when it is deserialized
Default: {}
public abstract String[] 替代
返回:字段反序列化时的替代名称
默认值:{}
回答by Mathieu Castets
In October 2015, Gson version 2.4(changelog) added the ability to use alternate/multiple names for @SerializedName
when deserializing. No more custom TypeAdapter needed!
2015 年 10 月,Gson 2.4 版( changelog) 添加了@SerializedName
在反序列化时使用备用/多个名称的功能。不再需要自定义 TypeAdapter!
Usage:
用法:
@SerializedName(value="name", alternate={"person", "user"})
回答by Mostafa Anter
for Kotlinfans
对于Kotlin粉丝
@SerializedName(value="name", alternate= ["person", "user"])
回答by android
For KOTLIN i used below but doesn't work
对于我在下面使用的 KOTLIN 但不起作用
@SerializedName(value="name", alternate= ["person", "user"])
so i edited it and here it works fine!!
所以我编辑了它,在这里它工作正常!!
@SerializedName(value="name", alternate= arrayOf("person", "user"))