我可以在不创建一堆模型的情况下从Gson转换器获取特定的变量值吗?

时间:2017-06-05 00:09:43

标签: android gson retrofit2

如果我有这样的回复

{
    "data": {
        "main_category": {"user":{"name":"Ali","age":5}}
    }
}

获取我的userModel>>

的预期方式
class User{
    String name;
    int age;
}

class MainCategory{
    User user;
}

class Data{
    MainCategory data;
}

有没有办法直接获取我的用户模型?像那样

class Data{
    @SerializedName("data/main_category/user")
    User user;
}

3 个答案:

答案 0 :(得分:0)

创建自定义反序列化器:

let leftOffset: CGFloat = 60
let rightOffset: CGFloat = 60

@objc override var frame: CGRect {
     didSet {
                let width: CGFloat = UIScreen.main.bounds.width - leftOffset - rightOffset
                let height: CGFloat = 44

                super.frame = CGRect(
                    x: leftOffset,
                    y: 20,
                    width: width,
                    height: height
                )
       }
}

然后创建一个像这样的gson构建器:

class MyDeserializer implements JsonDeserializer<Content>
{
    @Override
    public Content deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
        throws JsonParseException
    {

        JsonElement data = je.getAsJsonObject().get("data");
        JsonElement mainCategory = je.getAsJsonObject().get("main_category");
        JsonElement user = je.getAsJsonObject().get("user");

        return new Gson().fromJson(user, User.class);
    }
}

最后,在您的改造实例中分配gson构建器:

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

答案 1 :(得分:0)

由于数据丢失,以这种方式修改数据可能不是一个好主意。通常,(de)序列化库不鼓励您这样做。对于此类特定情况,在Gson中,必须隐式使用自定义(de)序列化程序(如果可能)或显式使用。但是,您可以像这样实现它:

final class UserResponse {

    @SerializedName("data")
    @JsonAdapter(UserSkippingJsonDeserializer.class)
    final User user = null;

}

上面的DTO使用了两个注释:

  • @SerializedName - 将JSON属性名称映射到字段名称
  • @JsonAdapter - 仅为此特定字段关联特定JSON类型适配器
final class User {

    final String name = null;
    final int age = Integer.valueOf(0); /* disable javac inlining */

}

现在,您可以创建模板方法JsonDeserializer来制作基元重映射作业:

abstract class SkippingJsonDeserializer<T>
        implements JsonDeserializer<T> {

    protected abstract JsonElement extract(JsonElement jsonElement);

    @Override
    public final T deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context)
            throws JsonParseException {
        return context.deserialize(extract(jsonElement), type);
    }

}

最后,定义User提取规则:

final class UserSkippingJsonDeserializer
        extends SkippingJsonDeserializer<User> {

    // Gson will instantiate it itself  
    private UserSkippingJsonDeserializer() {
    }

    @Override
    protected JsonElement extract(final JsonElement jsonElement) {
        return jsonElement.getAsJsonObject()
                .getAsJsonObject("main_category")
                .getAsJsonObject("user");
    }

}

测试出来:

final UserResponse userResponse = gson.fromJson(jsonReader, UserResponse.class);
System.out.println(userResponse.user.name);

将产生:

  

阿里

如果您想要一个更具表现力的实现,您必须使用类似JsonPath的东西并实现更复杂的JSON反序列化器。例如:https://stackoverflow.com/a/42510510/166589

答案 2 :(得分:0)

Up Answers对我有用 但我更喜欢在仅为一个类创建自定义deserielizer时再创建一个模型 这不是一般情况