简体   繁体   English

Gson 的自定义序列化器和反序列化器可以获取类/字段吗?

[英]Can Gson's custom serializers and deserializers get the class/field?

I am considering switching over to Gson.我正在考虑切换到 Gson。

From my beginner's knowledge, I know of two ways to implement custom serializers and deserializers:根据我初学者的知识,我知道实现自定义序列化器和反序列化器的两种方法:

  1. JsonSerializer and JsonDeserializer , and JsonSerializerJsonDeserializer ,以及
  2. TypeAdaptor . TypeAdaptor

Consider the following:考虑以下:

public class Pojo {
  @JsonAdaptor(MyCustomAdaptor.class)
  private Integer number;
}

class MyCustomAdaptor extends TypeAdaptor<Integer> {
  @Override
  public Integer read(JsonReader in) throws IOException {
    // ...
  }

  public void write(JsonWriter writer, Integer value) throws IOException {
    // ...
  }
}

I noticed that TypeAdaptor does not expose the Field of number .我注意到TypeAdaptor没有公开numberField Nor is this the case with JsonSerializer and JsonDeserializer . JsonSerializerJsonDeserializer也不是这种情况。 I understand that by the time these classes are used in the marshaling/unmarshalling lifecycle, there is no need to know this information.我知道当这些类用于编组/解组生命周期时,不需要知道这些信息。

For a moment, let's pretend that the Field was exposed in TypeAdaptor s.暂时,让我们假设Field暴露在TypeAdaptor中。 The following is a basic example of what I would do:以下是我会做的一个基本示例:

public class Pojo {
  @JsonAdaptor(MyCustomAdaptor.class)
  @FloatSerialize
  private Number number;
}

class MyCustomAdaptor extends TypeAdaptor<Number> {
  @Override
  public Number read(JsonReader in, Field field) throws IOException {
    // Do something if @FloatSerialize is present.
  }

  public void write(JsonWriter writer, Number value, Field field) throws IOException {
    // Do something if @FloatSerialize is present.
  }
}

I know this would not make sense because @JsonAdaptor can be used on classes and fields.我知道这没有意义,因为@JsonAdaptor可以用于类和字段。

Also, I know there are better ways to accomplish the above example;另外,我知道有更好的方法来完成上述示例; it is just an example and is meaningless.这只是一个例子,没有任何意义。 Basically, I want to use annotations, on a per-field basis, to tell custom serializers/deserializers how to process.基本上,我想在每个字段的基础上使用注释来告诉自定义序列化器/反序列化器如何处理。

Is this possible with Gson? Gson 这可能吗? Can you create a custom serializer/deserializer that exposes the annotated class/field/etc?您可以创建一个自定义序列化器/反序列化器来公开带注释的类/字段/等吗?

@JsonAdaptor(MyCustomAdaptor.class)
private Integer number;

You've annotated an Integer field.您已注释 Integer 字段。

I noticed that TypeAdaptor does not expose the Field of number我注意到 TypeAdaptor 没有公开数字的字段

I think there is something you misunderstand.我认为你误解了一些东西。

You provide the TypeAdaptor, you gives it the same type as your field:你提供 TypeAdaptor,你给它与你的字段相同的类型:

class MyCustomAdaptor extends TypeAdaptor<Integer>

Then at serialization, you have the java objet you've annotated as an input to serialize to a string, then you have your field directly available as 'value' in a parameter:然后在序列化时,您将 java 对象注释为输入以序列化为字符串,然后您的字段可直接用作参数中的“值”:

public void write(JsonWriter writer, Integer value) throws IOException

At deserialization, you have a json string as input to deserialize to the object you've annotated.在反序列化时,您有一个 json 字符串作为输入以反序列化到您已注释的 object。 In the type adaptor this object is your field, that's why read method return an Integer.在类型适配器中,这个 object 是您的字段,这就是 read 方法返回 Integer 的原因。

Integer read(JsonReader in) throws IOException

It's up to you to return an Integer from the JsonReader.从 JsonReader 返回 Integer 由您决定。

You can use a Number instead of an Integer for your field, then you can have float,integer,short and more in your field.您可以在您的字段中使用数字而不是 Integer,然后您可以在您的字段中使用浮点数、integer 等。

For this you bring a NumberAdaptor:为此,您需要带一个 NumberAdaptor:

class MyCustomAdaptor extends TypeAdaptor<Number> {
   
    Number read(JsonReader in, Field field) throws IOException;
    
    void write(JsonWriter writer, Number value) throws IOException; 
}

If you really want to think about 'field', then provide an adaptor for the whole objet:如果您真的想考虑“字段”,请为整个对象提供一个适配器:

class Pojo Adaptor extends TypeAdaptor< Pojo > {

  Pojo read(JsonReader in) throws IOException;

  void write(JsonWriter writer, Pojo value) throws IOException;
}

Then you have access to the whole object and its fields in the adaptor.然后您可以访问整个 object 及其在适配器中的字段。

Same things form JsonSerializer/JsonDeserialize.与 JsonSerializer/JsonDeserialize 相同。

With your additional info:使用您的附加信息:

class Pojo Adaptor extends TypeAdaptor< Pojo > {

  Pojo read(JsonReader in) throws IOException{
for(Field f: Pojo.class.getDeclaredFields()){
            f.steAccessible();
            for(Annotation a : f.getAnnotations()){
                // Do what you want here withe the field and its annotation
            }
    }

  void write(JsonWriter writer, Pojo value) throws IOException{

        for(Field f: Pojo.class.getDeclaredFields()){
            f.steAccessible();
            for(Annotation a : f.getAnnotations()){
                // Do what you want here with the field and its annotation
            }
        }
    }
}

I've wrote this from my memory but you've got the idea我是从我的 memory 写的,但你明白了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM