首页 > 技术文章 > 自定义 Gson 系列化

Alay 2021-08-08 18:29 原文

>>>>>>>>>>>>>  码云中有封装号的:https://gitee.com/chxlay/iserver-common.git   <<<<<<<<<<<<<<<<<<<<<

码云中: iserver-common-search  模块 有封装(作为 search 的系列化工具)
Gson 自定义系列化问题:

追踪  Gson 源码发现,Gson 获取每个字段的类系列化实现 TypeAdapt<?>,然后进行系列化,自定义系列化

 

自定义系列化器方式(两种方式):

1、继承类 TypeAdapter 方式: 只需要 自定义一个 Adapter<处理的类>  类,继承 TypeAdapter,实现重写系列化方法,写  write  读 read 方法即可;

2、实现类方式:                        JsonSerializer<处理的类> , 反系列化 JsonDeserializer<处理的类>,  实现相应的方法逻辑

 

使用方式(两种: 注解  或者  配置注册)

1、注解:             @JsonAdapter ( value = 系列化器类信息(继承,或 实现   的方式都可以的) )

2、全局配置注册:GsonBuilder()  --->> registerTypeAdapter( 类信息,自定义系列化器对象(继承,或 实现   的方式都可以的))

 如:

    protected static Gson GSON;
    static {
        GSON = new GsonBuilder()
                // 注册自定义金额分的系列化规则
                .registerTypeAdapter(MoneyPenny.class, new MoneyPennyAdapter())
                // 时间系列化规则
                .registerTypeAdapter(LocalDate.class,new LocalDateSerialization())
                .create();
    }

 


系列化器 示例(两种方式):

1、 继承 TypeAdapter<处理的类>

public class LocalDateAdapter extends TypeAdapter<LocalDate> {
   
   final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
   @Override
   public void write(JsonWriter jsonWriter, LocalDate date) throws IOException {
      jsonWriter.value(date.format(dateFormatter));
   }
   @Override
   public LocalDate read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
         in.nextNull();
         return null;
      } else {
         // 自定义的工具类,将 String 转成 LocalDate 类型
         LocalDate localDate = DateUtils.str2LDate(in.nextString(), "yyyy-MM-dd");
         return localDate;
      }
   }
}
public class LocalDateTimeAdapter extends TypeAdapter<LocalDateTime> {
 
   final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss");
 
   @Override
   public void write(JsonWriter jsonWriter, LocalDateTime dateTime) throws IOException {
      jsonWriter.value(dateTime.format(dateTimeFormatter));
   }
   @Override
   public LocalDateTime read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
         in.nextNull();
         return null;
      } else {
           // 自定义的工具类,将 String 转成 LocalDate 类型
         LocalDateTime localDateTime = DateUtils.str2LTime(in.nextString(), "yyyy-MM-ddHH:mm:ss");
         return localDateTime;
      }
   }
}

 自定义金额分:

public class MoneyPennyAdapter extends TypeAdapter<MoneyPenny> {
    @Override
    public void write(JsonWriter jsonWriter, MoneyPenny moneyPenny) throws IOException {
        jsonWriter.value(moneyPenny.toString());
    }
    @Override
    public MoneyPenny read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        } else {
            return new MoneyPenny(in.nextString());
        }
    }
}

 


2、实现   JsonSerializer<处理的类>, JsonDeserializer<处理的类>

LocalDate:

public class LocalDateSerialization implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> {
    final DateTimeFormatter format = DatePattern.NORM_DATE_FORMATTER;
    @Override
    public JsonElement serialize(LocalDate localDate, Type type, JsonSerializationContext context) {
        return context.serialize(LocalDateTimeUtil.format(localDate, format));
    }
    @Override
    public LocalDate deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        return LocalDateTimeUtil.parseDate(json.getAsString(), format);
    }
}

LocalDateTime:

public class LocalDateTimeSerialization implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
    final DateTimeFormatter format = DatePattern.NORM_DATETIME_FORMATTER;
    @Override
    public JsonElement serialize(LocalDateTime localDateTime, Type type, JsonSerializationContext context) {
        return context.serialize(LocalDateTimeUtil.format(localDateTime, format));
    }
    @Override
    public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        return LocalDateTimeUtil.parse(json.getAsString(), format);
    }
}

 自定义金额系列化:

public class MoneyPennySerialization implements JsonSerializer<MoneyPenny>, JsonDeserializer<MoneyPenny> {
    @Override
    public JsonElement serialize(MoneyPenny penny, Type type, JsonSerializationContext context) {
        return context.serialize(penny.toString());
    }
    @Override
    public MoneyPenny deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        return new MoneyPenny(json.getAsString());
    }
}

 


使用(两种方式):

1: 注解方式:

@Data
public class TestGsonEntity implements Serializable {
    /**
     * 使用 GsonBuilder() 注册  TypeAdapter<MoneyPenny> 方式实现
     */
    private MoneyPenny balance;
    /**
     * 使用 GsonBuilder() 注册 JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> 实现类方式
     */
    private LocalDate birthday;
    /**
     * 使用:@JsonAdapter 配置 JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> 实现类的方式
     */
    @JsonAdapter(value = LocalDateTimeSerialization.class)
    private LocalDateTime createTime;
    /**
     * 使用:@JsonAdapter 配置 TypeAdapter<LocalDateTime> 实现类的方式
     */
    @JsonAdapter(value = LocalDateTimeAdapter.class)
    private LocalDateTime updateTime;
    /**
     * 忽略的字段测试(其实是 null 值处理)
     */
    @JsonAdapter(value = GsonNullValueAdapter.class)
    private String ignoreValue1;
    @JsonAdapter(value = GsonNullValueAdapter.class)
    private Integer ignoreValue2;
}

 

全局配置注册方式:

或者 在创建 GSON 对象实例的时候将 类型西与 系列化器注册绑定

    protected static Gson GSON;
    static {
        GSON = new GsonBuilder()
                // 注册自定义金额分的系列化规则
                .registerTypeAdapter(MoneyPenny.class, new MoneyPennyAdapter())
                // 时间系列化规则
                .registerTypeAdapter(LocalDate.class,new LocalDateSerialization())
                .create();
    }

 


 同样的思路自定义忽略 GSON 系列化类

public class GsonNullValue extends TypeAdapter<Object> {
    @Override
    public void write(JsonWriter jsonWriter, Object source) throws IOException {
        // 忽略的字段,直接返回 null
        jsonWriter.nullValue();
    }
    @Override
    public Object read(JsonReader jsonReader) throws IOException {
        // 忽略的字段,直接返回 null
        return null;
    }
}

 

推荐阅读