当前位置: 首页 > 知识库问答 >
问题:

使用TypeAdapter为对象中的一个变量(多个变量中的一个)定制seralizer

拓拔富
2023-03-14
public class MyClass extends SomeClass {

@Expose private HashMap<String, MyObject1> lists;
@Expose private HashMap<String, MyObject2> sources;
private LinkedHashMap<String, SomeClass> customSerializeThis;
    [snip]
}

共有1个答案

田彬郁
2023-03-14

这是一个很好的问题,因为它隔离了一些应该很容易但实际上需要大量代码的东西。

首先,编写一个抽象的typeAdapterFactory,为您提供修改传出数据的钩子。这个示例使用了GSON2.2中的一个新API,名为getdelegateadapter(),它允许您查找Gson默认使用的适配器。如果您只想调整标准行为,委托适配器非常方便。与完整的自定义类型适配器不同,当您添加和删除字段时,它们将自动保持最新状态。

public abstract class CustomizedTypeAdapterFactory<C>
    implements TypeAdapterFactory {
  private final Class<C> customizedClass;

  public CustomizedTypeAdapterFactory(Class<C> customizedClass) {
    this.customizedClass = customizedClass;
  }

  @SuppressWarnings("unchecked") // we use a runtime check to guarantee that 'C' and 'T' are equal
  public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    return type.getRawType() == customizedClass
        ? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type)
        : null;
  }

  private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) {
    final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
    final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
    return new TypeAdapter<C>() {
      @Override public void write(JsonWriter out, C value) throws IOException {
        JsonElement tree = delegate.toJsonTree(value);
        beforeWrite(value, tree);
        elementAdapter.write(out, tree);
      }
      @Override public C read(JsonReader in) throws IOException {
        JsonElement tree = elementAdapter.read(in);
        afterRead(tree);
        return delegate.fromJsonTree(tree);
      }
    };
  }

  /**
   * Override this to muck with {@code toSerialize} before it is written to
   * the outgoing JSON stream.
   */
  protected void beforeWrite(C source, JsonElement toSerialize) {
  }

  /**
   * Override this to muck with {@code deserialized} before it parsed into
   * the application type.
   */
  protected void afterRead(JsonElement deserialized) {
  }
}

上面的类使用默认序列化获得JSON树(由JSONElement表示),然后调用钩子方法BeforeWrite()允许子类自定义该树。类似地,对于使用afterread()进行反序列化。

private class MyClassTypeAdapterFactory extends CustomizedTypeAdapterFactory<MyClass> {
  private MyClassTypeAdapterFactory() {
    super(MyClass.class);
  }

  @Override protected void beforeWrite(MyClass source, JsonElement toSerialize) {
    JsonObject custom = toSerialize.getAsJsonObject().get("custom").getAsJsonObject();
    custom.add("size", new JsonPrimitive(custom.entrySet().size()));
  }

  @Override protected void afterRead(JsonElement deserialized) {
    JsonObject custom = deserialized.getAsJsonObject().get("custom").getAsJsonObject();
    custom.remove("size");
  }
}
Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(new MyClassTypeAdapterFactory())
    .create();
 类似资料:
  • 为什么我不能这样做? 我得到: 致命错误:常量表达式包含无效操作 这有什么办法吗?

  • 我已经编写了这个预期输出的代码: 输入样本: 输入乘客姓名:Priya 输入性别(M或F/m或f):F 输入年龄:61 请输入票号:140 输入票价:500.0 示例输出1: 票号:143 乘客姓名:Priya 一张票的价格: 500.0 总金额: 375.0 我必须根据我所写函数的年龄和性别来更改总量值。 我的代码: Person.java BusTicket.java TestMain.jav

  • 问题内容: 我试图了解变量如何在python中工作。说我有一个对象存储在变量中: 如果我分配给,则它们都指向同一个对象: 但是,如果我重新分配或,那就不再正确了: 这两个变量现在具有不同的值: 我不明白为什么变量现在不同。为什么不再是真的?有人可以解释发生了什么吗? 问题答案: Python具有引用 对象的 名称 。对象与名称分开存在,名称与它们引用的对象分开存在。 __ 在为“名称分配名称”时,

  • 问题内容: 我正在尝试将输入字段的值绑定到变量。我不知道这个变量的名字 是先验的 ;它存储在另一个变量中。 这是html: 这是控制器: 我也 弄了个小提琴。 这是行不通的,因为当前绑定是在输入字段和变量之间。相反,我将输入字段绑定到变量,该变量的名称存储在变量中(在本例中为)。 可能吗? 怎么样? 问题答案: 是的,有可能。我不明白您为什么要这样做,但是我可以告诉您如何做。我无法启动小提琴,但是

  • 问题内容: 我的探针示例: 我们有Apple的对象类型。苹果有一些成员变量: 种子对象如下所示。 现在,当我得到一个苹果物体时,一个苹果可能有多个种子,或者可能有一个种子,或者可能没有种子! 带有一个种子的示例JSON苹果: 带有两个种子的示例JSON苹果: 现在的问题是,第一个示例是用于种子的JSONObject,第二个示例是用于种子的JSONArray。现在,我知道它的JSON不一致,并且最简

  • 问题内容: 我的探针示例: 我们有Apple的对象类型。苹果有一些成员变量: 种子对象如下所示。 现在,当我得到一个苹果物体时,一个苹果可能有多个种子,或者可能有一个种子,或者可能没有种子! 带有一个种子的示例JSON苹果: 带有两个种子的示例JSON苹果: 现在的问题是,第一个示例是用于种子的JSONObject,第二个示例是用于种子的JSONArray。现在,我知道它的JSON不一致,并且最简