一尘不染

如何序列化可选 和Gson一起上课?

json

我有一个具有以下属性的对象。

private final String messageBundle;
private final List<String> messageParams;
private final String actionBundle;
private final Map<String, String> data;
private final Optional<Pair<Integer,TimeUnit>> ttl;
private final Optional<Integer> badgeNumber;
private final Optional<String> collapseKey;

该对象位于库中,我宁愿不要仅出于序列化目的对其进行修改,并且希望避免创建另一个DTO的开销。

如何序列化/反序列化Optional属性?Optional没有默认的构造函数(两者都不是apache commons
Pair),但是我不能使用InstanceCreator,也不真正理解如何创建TypeAdapter来将序列化委托给底层的Optional内容。


阅读 193

收藏
2020-07-27

共1个答案

一尘不染

Ilya的解决方案忽略类型参数,因此在一般情况下它实际上无法工作。我的解决方案相当复杂,因为需要区分nullOptional.absent()-否则您可以将封装剥离为列表。

public class GsonOptionalDeserializer<T>
implements JsonSerializer<Optional<T>>, JsonDeserializer<Optional<T>> {

    @Override
    public Optional<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        final JsonArray asJsonArray = json.getAsJsonArray();
        final JsonElement jsonElement = asJsonArray.get(0);
        final T value = context.deserialize(jsonElement, ((ParameterizedType) typeOfT).getActualTypeArguments()[0]);
        return Optional.fromNullable(value);
    }

    @Override
    public JsonElement serialize(Optional<T> src, Type typeOfSrc, JsonSerializationContext context) {
        final JsonElement element = context.serialize(src.orNull());
        final JsonArray result = new JsonArray();
        result.add(element);
        return result;
    }
}
2020-07-27