问题描述
我为Person类创建了一个自定义反序列化器.这只是出于演示目的.我的实际课堂更加复杂.
I created a custom deserializer for my Person class. This is just for demonstration purpose. My actual class is more complicated.
json文件包含格式的版本,然后是一系列人.
The json file contains the version of the format and after that an array of persons.
在1.0版上,我每个人都有一个姓名和年龄.
在2.0版中,我有一个名称,年龄以及一个性别.
On version 1.0 i have a name and age for every person.
On version 2.0 i have a name, age and additionally the gender.
我的问题是我无法访问自定义反序列化器中的版本,或者至少还没有弄清楚如何获得它.
My problem here is that i do not have access to the version in the custom deserializer, or at least didn't figure out how to get it yet.
还有其他方法可以在没有jsonObj.get("gender").has();
的情况下执行此操作吗?还是if (jsonObj.get("gender") != null)
?
Is there any other way to do this without jsonObj.get("gender").has();
or if (jsonObj.get("gender") != null)
?
GSON版本:2.8.5
GSON Version: 2.8.5
反序列化器:
private class PersonDeserializer implements JsonDeserializer<PersonDatapoint>
{
@Override
public PersonDatapoint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject jsonObj = json.getAsJsonObject();
// version 1.0
Person person = new Person(jsonObj.get("name").getAsString());
person.setAge(jsonObj.get("age").getAsInt());
// version 2.0
// how to determine version field in json File?
// person.setGender(jsonObj.get("gender").getAsString());
return person;
}
}
JSON文件v1.0:
{
"version": "1.0",
"persons": [
{
"name": "Alex",
"age": 30
},
{
"name": "John",
"age": 31
},
{
"name": "Elise",
"age": 32
}]
}
JSON文件v2.0:
{
"version": "2.0",
"persons": [
{
"name": "Alex",
"age": 30,
"gender": "male"
},
{
"name": "John",
"age": 31,
"gender": "male"
},
{
"name": "Elise",
"age": 32,
"gender": "female"
}]
}
推荐答案
要访问版本字段,请不要使人使用JsonDeserializer,而要使您拥有整个JSON.因此,让我们假设您的JSON是某种响应,可以通过以下Java类来呈现:
To have access to version field do not make JsonDeserializer for person but for the whole JSON you have. So let us assume your JSON is some kind of a response that could be presented with a Java class like:
@Getter @Setter
public class Response {
private Double version;
private Person[] persons; // versioned stuff
}
您班上的Person可能是这样的:
Your class Person might be like:
@Getter @Setter
public class Person {
@Since(1.0) // these annotations are put just for demonstrative purpose but are
// actually also functional, see deserializer
private String name;
@Since(1.0)
private Integer age;
@Since(2.0)
private String gender;
}
注意:该Person是一个有点糟糕的示例类,因为无需使用v1.0或v2.0 JSON中的任何自定义反序列化器,就可以轻松对它进行反序列化.从v1.0开始反序列化只会将gender
保留为空.无论如何,您的自定义反序列化器-使用JSON字段版本-可能看起来像这样:
Note: This Person is a bit bad example class since it could easily be deserialized without any custom deserializer from v1.0 or v2.0 JSON. Deserializng from v1.0 would just leave gender
null. Anyway your custom deserializer - making use of JSON field version - might then look like:
public class ResponseDeserializer implements JsonDeserializer<Response> {
@Override
public Response deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
// This is how to get the version
Double version = json.getAsJsonObject().get("version").getAsDouble();
// and below is jsut an example what you could do with version
Gson gson = new GsonBuilder()
.setVersion(version) // this is where @Since might be handy
.setPrettyPrinting()
.create();
return gson.fromJson(json, Response.class);
}
}
这篇关于Java GSON自定义反序列化器版本控制支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!