为了账号安全,请及时绑定邮箱和手机立即绑定

使用改进使用GSON获取嵌套的JSON对象

使用改进使用GSON获取嵌套的JSON对象

呼啦一阵风 2019-07-29 15:13:34
使用改进使用GSON获取嵌套的JSON对象我正在从我的Android应用程序中使用API,并且所有JSON响应都是这样的:{     'status': 'OK',     'reason': 'Everything was fine',     'content': {          < some data here >}问题是,我所有的POJO有status,reason字段,里面content领域是真正的POJO我想要的。有没有办法创建一个Gson的自定义转换器来提取总是content字段,所以改造返回适当的POJO?
查看完整描述

3 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

您将编写一个返回嵌入对象的自定义反序列化器。

假设您的JSON是:

{
    "status":"OK",
    "reason":"some reason",
    "content" : 
    {
        "foo": 123,
        "bar": "some value"
    }}

然后你有一个ContentPOJO:

class Content{
    public int foo;
    public String bar;}

然后你写一个反序列化器:

class MyDeserializer implements JsonDeserializer<Content>{
    @Override
    public Content deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
        throws JsonParseException
    {
        // Get the "content" element from the parsed JSON
        JsonElement content = je.getAsJsonObject().get("content");

        // Deserialize it. You use a new instance of Gson to avoid infinite recursion
        // to this deserializer
        return new Gson().fromJson(content, Content.class);

    }}

现在,如果您构造一个Gsonwith GsonBuilder并注册反序列化器:

Gson gson = 
    new GsonBuilder()
        .registerTypeAdapter(Content.class, new MyDeserializer())
        .create();

您可以直接将您的JSON反序列化为Content

Content c = gson.fromJson(myJson, Content.class);

编辑以添加评论:

如果您有不同类型的消息但它们都具有“内容”字段,则可以通过执行以下操作使反序列化器具有通用性:

class MyDeserializer<T> implements JsonDeserializer<T>{
    @Override
    public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
        throws JsonParseException
    {
        // Get the "content" element from the parsed JSON
        JsonElement content = je.getAsJsonObject().get("content");

        // Deserialize it. You use a new instance of Gson to avoid infinite recursion
        // to this deserializer
        return new Gson().fromJson(content, type);

    }}

您只需为每种类型注册一个实例:

Gson gson = 
    new GsonBuilder()
        .registerTypeAdapter(Content.class, new MyDeserializer<Content>())
        .registerTypeAdapter(DiffContent.class, new MyDeserializer<DiffContent>())
        .create();

当你调用.fromJson()类型被带入反序列化器时,它应该适用于所有类型。

最后在创建Retrofit实例时:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();


查看完整回答
反对 回复 2019-07-29
  • 3 回答
  • 0 关注
  • 962 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信