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

Gson自定义类型适配器是否仅在一种对象类型上序列化null?

农均
2023-03-14

我只想在JSON主体中序列化一种类型的null,该类型将进行PUT。我不想序列化对象中任何其他类型的null。我有这样的想法:

public class Patient {
    public Address address;
    public String first_name;
    public String last_name;
}

我只想在地址为空时序列化地址。比如说

Patient patient = new Patient();
patient.address = null;
patient.last_name = "Doe";

看起来像这样:

"address":null,
"last_name":"Doe"

当address被分配为null时,patient将不在对象中,因为默认情况下Gson不会序列化null(这是我想要的),last name保留分配的字符串值。

是否有Gson自定义类型适配器可供我使用?

public class GsonCustomAdapter extends TypeAdapter<Address>

我对这个概念一点也不熟悉,并且已经试着理解了一段时间。非常感谢您的帮助。

共有1个答案

夹谷信鸿
2023-03-14

如果默认情况下,您不想序列化空值,您可以告诉JsonWriter仅在实际读取地址实例时才序列化它。

让我们假设以下类别:

class Address {
    public String country = "UK";
    public String city = "London";
}

现在我们为地址类创建一个特定的类型适配器。在这里,您明确地说,即使JsonWriter不应该在响应中写入null值,您也允许它只在地址字段中这样做(参见代码中的注释)。

class AddressAdapter extends TypeAdapter<Address> {
    @Override
    public void write(JsonWriter out, Address address) throws IOException {
        if (address == null) {
            //if the writer was not allowed to write null values
            //do it only for this field
            if (!out.getSerializeNulls()) {
                out.setSerializeNulls(true);
                out.nullValue();
                out.setSerializeNulls(false);
            } else {
                out.nullValue();
            }
        } else {
            out.beginObject();
            out.name("country");
            out.value(address.country);
            out.name("city");
            out.value(address.city);
            out.endObject();
        }
    }

    @Override
    public Address read(JsonReader in) throws IOException {
        if(in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        in.beginObject();
        Address address = new Address();
        in.nextName();
        address.country = in.nextString();
        in.nextName();
        address.city = in.nextString();
        in.endObject();
        return address;
    }
}

现在必须注册这个适配器,以便解析器知道在序列化/反序列化地址字段时必须使用它。为此,请使用注释@JsonAdapter

class Patient {
    @JsonAdapter(AddressAdapter.class)
    public Address address;
    public String first_name;
    public String last_name;
}

它完成了!

例如,让我们以你的例子中的病人为例:

Patient patient = new Patient();
patient.last_name = "Doe";

将解析器设置为序列化空值,您将获得:

{"address":null,"first_name":null,"last_name":"Doe"}

不允许时(默认设置):

{"address":null,"last_name":"Doe"}

通过设置患者的地址:

patient.address = new Address();
...
{"address":{"country":"UK","city":"London"},"last_name":"Doe"}

需要注意的是,如果您想在Java方面遵守命名约定,可以使用注释@SerializedName,例如:

@SerializedName("first_name") public String firstName;
@SerializedName("last_name")  public String lastName;

希望有帮助!:-)

 类似资料:
  • 主要内容:创建自定义适配器,注册自定义适配器,使用适配器Gson使用其内置适配器执行对象的序列化/反序列化。 它也支持自定义适配器。 让我们来讨论如何创建一个自定义适配器以及如何使用它。 创建自定义适配器 通过扩展类并传递目标类型的对象来创建自定义适配器。 重写读写方法分别执行自定义的反序列化和序列化。 注册自定义适配器 使用注册自定义适配器并使用创建一个Gson实例。参考以下实现代码 - 使用适配器 Gson现在将使用自定义适配器将Json文本转换为

  • 问题内容: 下面的示例显示了一个类(Club),其中包含抽象类(成员)的集合。我对于是否需要TypeAdapter或JsonDeserializer才能使反序列化正常工作感到困惑。序列化在没有任何帮助的情况下就可以正常工作,但是反序列化会引发异常。为了说明这一点,我构建了以下“克隆”测试。如果有人能展示一个有效的例子,我将不胜感激。 头等舱 现在是抽象基类成员 以及成员的两个具体子类(金和银​​)

  • 我想通过Google Gson传输一个列表对象,但我不知道如何反序列化泛型类型。 我在看了这个之后尝试了什么(Balusc的回答): 编辑: 现在我有 但是,我确实在“FromJson”行得到以下异常: null

  • 也许我跑错了方向,但我有一个元素列表,我想读。 我有一个抽象基类,让我们称之为: 现在我有两个可能的实现:

  • 问题内容: 我有一些奇怪的JSON,如: 基于某个字段,数组中的对象是某种类型。使用Gson,我的想法是要拥有一个TypeAdapterFactory,它将那些特定类型的委托适配器发送到TypeAdapter,但是我一直挂在理解读取“ type”字段以了解要创建哪种类型的一种好方法上。在TypeAdapter中 会假设“类型”字段在我的JSON中排在首位。有消除这种假设的不错方法吗? 问题答案:

  • Gson使用其内置适配器执行对象的序列化/反序列化。 它还支持自定义适配器。 我们将讨论如何创建自定义适配器以及如何使用它。 创建自定义适配器 通过扩展TypeAdapter类并将其传递给目标对象的类型来创建自定义适配器。 重写read和write方法以分别执行自定义反序列化和序列化。 class StudentAdapter extends TypeAdapter<Student> {