Gson RuntimeTypeAdapterFactory在反序列化后将我的userType转换为null

tkqqtvp1  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(141)

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

[
  {
    "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类中:

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中,“所有者”和“常规”类:
第一个
我如何编写RuntimeTypeAdapaterFactory和方法以从json加载。

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;
    }
qybjjes1

qybjjes11#

您必须使用RuntimeTypeAdapterFactory.of(Class<T> baseType, String typeFieldName, boolean maintainType)重载并指定maintainType=true。否则Gson在分配字段值时将忽略其值。
然而,问题是User类是否真的需要userType字段,Gson在使用RuntimeTypeAdapterFactory时不需要它,如果在应用程序逻辑中需要用户类型值,也许让User声明一个抽象的getUserType()方法,然后子类覆盖该方法会更简洁(例如Admin会将其实作为return UserType.ADMIN)。使用您目前的实作,(理论上)Regular可能会有使用者类型ADMIN

相关问题