首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gson RuntimeTypeAdapterFactory在反序列化之后将我的userType转换为空。

Gson RuntimeTypeAdapterFactory在反序列化之后将我的userType转换为空。
EN

Stack Overflow用户
提问于 2021-10-23 15:07:19
回答 1查看 131关注 0票数 0

我正在使用来自https://github.com/google/gson/blob/master/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.javahttps://github.com/google/gson/blob/master/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java,并试图从包含以下值的userData.json文件中将json反序列化为用户对象:

代码语言:javascript
复制
[
  {
    "id": "a66c4e96-3370-47e3-a757-d7d9417208db",
    "userType": "ADMIN",
    "firstName": "admin1",
    "lastName": "adminlast1",
    "username": "admin0101",
    "email": "abc1@abc.com",
    "password": "abc123",
    "address": null
  },
  {
    "id": "4948f8c4-7c89-4b7a-92a8-a0ed9daa5b39",
    "userType": "REGULAR",
    "firstName": "regular1",
    "lastName": "regularlast1",
    "username": "regular0101",
    "email": "abc2@abc.com",
    "password": "abc123",
    "address": null
  },
  {
    "id": "9dc587e1-b8e1-441a-a036-44cd091ce405",
    "userType": "OWNER",
    "firstName": "owner1",
    "lastName": "ownerlast1",
    "username": "owner0101",
    "email": "abc3@abc.com",
    "password": "abc123",
    "address": null
  }
]

但是,当我试图从.json文件中读取它们时,userType变成了null,如下所示:

在我的User课上:

代码语言:javascript
复制
public class User {
    private String id;
    protected UserType userType;
    private String firstName;
    private String lastName;
    private String username;
    private String email;
    private String password;
    private String address;

    public User(String id, UserType userType, String firstName, String lastName, String username, String email, String password, String address) {
        this.id = id;
        this.userType = userType;
        this.firstName = firstName;
        this.lastName = lastName;
        this.username = username;
        this.email = email;
        this.password = password;
        this.address = address;
    }
}

在我的Admin中,“所有者”和“常规”类:

代码语言:javascript
复制
public class Admin extends User{
    private String adminDetails;
    public Admin(String id, String firstName, String lastName, String username, String email, String password, String address, String adminDetails) {
        super(id, UserType.ADMIN, firstName, lastName, username, email, password, address);
        this.adminDetails = adminDetails;
    }
}
代码语言:javascript
复制
public class Owner extends User{
    private String ownerDetails;
    public Owner(String id, String firstName, String lastName, String username, String email, String password, String address, String ownerDetails) {
        super(id, UserType.OWNER, firstName, lastName, username, email, password, address);
        this.ownerDetails = ownerDetails;
    }
}
代码语言:javascript
复制
public class Regular extends User{
    private String regularDetails;
    public Regular(String id, String firstName, String lastName, String username, String email, String password, String address, String regularDetails) {
        super(id, UserType.REGULAR, firstName, lastName, username, email, password, address);
        this.regularDetails = regularDetails;
    }
}

我是如何编写从json加载的RuntimeTypeAdapaterFactory和方法的。

代码语言:javascript
复制
 private final Type USER_LIST_TYPE = new TypeToken<ArrayList<User>>(){}.getType();

    //used for deserialization of User
    RuntimeTypeAdapterFactory<User> adapter = RuntimeTypeAdapterFactory.of(User.class, "userType")
            .registerSubtype(Admin.class, UserType.ADMIN.name())
            .registerSubtype(Owner.class, UserType.OWNER.name())
            .registerSubtype(Agent.class, UserType.AGENT.name())
            .registerSubtype(Regular.class, UserType.REGULAR.name())
            .registerSubtype(Pending.class, UserType.PENDING.name());

    //load from json file based on provided UserType
    private ArrayList<User> loadData(UserType userType){
        try {
            fileReader = new FileReader(getPath(loadDataType));
            gson = new GsonBuilder().registerTypeAdapterFactory(adapter).create();
            reader = new JsonReader(fileReader);
            data = gson.fromJson(reader, USER_LIST_TYPE);
            fileReader.close();


        } catch (IOException e) {
            e.printStackTrace();
        }
        if (data == null){
            return new ArrayList<User>();
        }

        return data;
    }
EN

回答 1

Stack Overflow用户

发布于 2021-10-29 10:09:43

您必须使用RuntimeTypeAdapterFactory.of(Class<T> baseType, String typeFieldName, boolean maintainType)重载并指定maintainType=true。否则,当分配字段值时,Gson将忽略其值。

但是,问题是您的User类是否真的需要一个userType字段。在使用RuntimeTypeAdapterFactory时,Gson不需要这样做。如果您需要应用程序逻辑中的用户类型值,那么让User声明一个抽象的getUserType()方法,然后重写子类(例如,Admin会将其实现为return UserType.ADMIN)也许会更好。使用当前的实现,(理论上) Regular具有用户类型的ADMIN是可能的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69689389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档