【问题标题】:Parsing JSON to Enum Fields将 JSON 解析为枚举字段
【发布时间】:2014-01-14 14:21:27
【问题描述】:

在我的 Android 应用程序中,我返回了一个带有简单键值对的简单 JSON 对象,例如:

{"username" : "billySmith", "gender" : 1}

还有一个具有各自字段名称usernamegender 的枚举(分别为String 和int)。

我正在尝试使用 Gson 解析 JSON 对象并使用 json 值填充枚举字段。我有点不确定如何将 GSON 与枚举一起使用。我熟悉应该将对象的实例设置为等于gson.fromJson(jsonObect, instanceType.class); 的概念。

为了添加更多细节,我使用 Enums 以便可以从我的 android 项目中的任何位置检索值。

if (response.getStatusLine().getStatusCode() == 200 && result != "")
{                               
    GlobalEnum globalEnum = GlobalEnum.getInstance();
    Gson gson = new GsonBuilder().create();
    globalEnum = gson.fromJson(result, GlobalEnum.class);
}

其中“结果”是 HTTP 响应实体的字符串表示形式

GlobalEnum sn-p:

public enum GlobalEnum
{
    INSTANCE;

    private String username;
    private int gender;

    public static GlobalEnum getInstance()
    {
        return INSTANCE;
    }

    public int getGender()
    {
        return gender;
    }

    public void setGender(int gender)
    {
        this.gender = gender;
    }
}

*编辑: 改写:我有一个枚举,我有一个 jsonObject。枚举和 JSON 对象都有“用户名”和“性别”。使用 Gson,我想解析 JSON 对象,以便将 JSON 对象中的值分配给枚举中的相应字段。

【问题讨论】:

  • 你能贴出GlobalEnum的代码吗?
  • 您是否为预定义用户设置了固定的用户名/性别值?
  • 是的,专门用于测试应用程序,这样我就不必每次运行时都手动输入信息。但是我需要在整个应用程序中全局存储其他东西,例如登录时生成的访问令牌

标签: java android json enums gson


【解决方案1】:

正如我在评论中所说,您需要创建一个类型适配器才能在 json 解析期间获取您的枚举。这是我为我的目的所做的一个例子。 在您的枚举中创建TypeAdapterFactory gsonTypeAdaptor,如下所示:

public static TypeAdapterFactory gsonTypeAdaptor = new TypeAdapterFactory() {
        @Override
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
            Class<T> rawType = (Class<T>) type.getRawType();
            if (!(rawType.isEnum() && Predicates.assignableFrom(rawType).apply(<your enum>.class))) {
                return null;
            }
            return new TypeAdapter<T>() {
                public void write(JsonWriter out, T value) throws IOException {
                    if (value == null) {
                        out.nullValue();
                    } else {
                        out.value(((<your enum>)value).name);
                    }
                }
                public T read(JsonReader reader) throws IOException {
                    if (reader.peek() == JsonToken.NULL) {
                        reader.nextNull();
                        return null;
                    } else {
                        return (T) <get your enum by using reader.nextString()>;
                    }
                }
            };
        }
    };

一个适配器已就位,将其注册到您的gson builder,如下所示: builder.registerTypeAdapterFactory(&lt;your enum&gt;.gsonTypeAdaptor);

让我知道这是否有用。

【讨论】:

    【解决方案2】:

    您可能误解了Java 中Enum 的含义。它们通常不应该像这样在运行时对修改开放。

    我想下面的逻辑会更好地为您服务,在将JSON 解析为Enums 时避免您遇到这种麻烦。

    首先,一个UserInformation Java Bean 类,包装了usernamegender 字段:

    public class UserInformation
    {
        private String username;
        private int gender;
    
        public UserInformation(String username, int gender)
        {
            this.username = username;
            this.gender = gender;
        }
    
        public String getUsername()
        {
            return username;
        }
        public void setUsername(String username)
        {
            this.username = username;
        }
        public int getGender()
        {
            return gender;
        }
        public void setGender(int gender)
        {
            this.gender = gender;
        }
    }
    

    然后将您的 GlobalEnum 类重命名为 GlobalValues 并修改为用作值容器:

    public abstract class GlobalValues
    {
        // You can also create get/set methods for encapsulation if you want
        public static UserInformation userInformation;
    }
    

    然后是您将 JSON 字符串解析为 UserInformation 对象的逻辑,然后将其存储在您的 GlobalValues 类中。

    String jsonStr = "{\"username\" : \"billySmith\", \"gender\" : 1}";
    
    Gson gson = new Gson();
    
    GlobalValues.userInformation = gson.fromJson(jsonStr, UserInformation.class);
    

    【讨论】:

    • 谢谢。我更清楚地理解这背后的逻辑。但是我遇到了一个错误。我已经初始化了以下内容:UserInformation userInformation = GlobalValues.userInformation;。当我尝试在这个实例上调用 setter/getter 时,我收到一个空指针异常......即使我只是调用 GlobalValues.userInformation 的 getter 和 setter,我仍然会收到异常......
    • GlobalValues.userInformation 将保持为空,直到您第一次加载它们。您可能必须实例化并填充您的 UserInformation 对象,然后将它们设置为 GlobalValues.userInformation
    • 我将 GlobalValue 范围内的 public static UserInformation userInformation; 替换为 public static UserInformation userInformation = new userInformation(),如果我使用 GlobalValues.userInformation 引用该实例,现在似乎一切正常。这看起来合理吗?
    • 是的,你可以这样做。
    • 非常感谢!这实际上也解决了我之前使用 GSON 时遇到的另一个问题!
    猜你喜欢
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多