Java 在gson中使用自定义typeadapter jsonwriter添加对象

Java 在gson中使用自定义typeadapter jsonwriter添加对象,java,json,gson,Java,Json,Gson,gson是一个很棒的图书馆——它工作得很好。有时我有定制需求,可以制作和注册TypeAdapter和TypeAdapterFactorys,这也很有效 然而,让我困惑的是,如何委托回json序列化。。。大多数情况下,我需要将其用于集合,但为了说明这一点,假设我有一个pair类,gson显然很乐意序列化它,但出于某种原因,我需要自己的自定义序列化程序。好。。。如果我的鞋是 public class Pair { public final Object First; public f

gson是一个很棒的图书馆——它工作得很好。有时我有定制需求,可以制作和注册TypeAdapter和TypeAdapterFactorys,这也很有效

然而,让我困惑的是,如何委托回json序列化。。。大多数情况下,我需要将其用于集合,但为了说明这一点,假设我有一个pair类,gson显然很乐意序列化它,但出于某种原因,我需要自己的自定义序列化程序。好。。。如果我的鞋是

public class Pair
{
    public final Object First;
    public final Object Second; 
    public Pair( Object first, Object second) {this.first = first; this.second = second};
}
如果我为此编写了一个类型适配器,您可能希望write函数如下所示:

public void write( JsonWriter out, Pair pair )
{
    out.beginObject();
    out.name( "first");
    out.value( pair.first );         // can't do this
    out.name( "second");
    out.value( pair.second);         // or this
    out.endObject();
}
所以你可以看到问题所在——我不知道第一个和第二个的类型,也不知道它们是如何序列化的。我可以使用gson.toJson序列化第一个和第二个,但是如果我将它们作为字符串添加到编写器中,它们将被转义。有一个gson.tojson函数,它接受一个值和一个writer,但它也接受一个typetoken,这是我没有的。我有一种感觉,我是想从某处得到另一个类型适配器——但是当我只有一个对象列表时。。。我从哪里得到的?我是否只获取对象的适配器

我有点困惑?这肯定是最常见的用例吗?大多数自定义序列化程序将用于奇怪的T列表或T树或其他内容,您真的不知道列表中有什么,除了它继承自T。。。所以您需要能够以某种方式委托回序列化


无论如何,如果有人能告诉我如何编写上述函数,我将非常感激

实际上,这似乎是可行的—为对象获取适配器—使用TypeAdapterFactory在对象上发现一个“json”方法,并将该方法存储在适配器对象中。对于这样一个显而易见的用例来说,它似乎异常复杂

例如:

public static@Nullable
类型适配器>()
{
@凌驾
公共ImmutableStack读取(@Nullable final JsonReader in)引发IOException
{
抛出ProgramError.notImplementedYet();
}
@凌驾
公共void write(最终JsonWriter out,最终ImmutableStack值)引发IOException
{
out.beginArray();
用于(最终对象内部:值)
适配器。写入(输出,内部);
out.endArray();
}
};
}

有人知道更好的方法吗?

在这种情况下,最好使用a而不是a,原因很简单,序列化程序可以访问其序列化上下文:

public class PairSerializer implements JsonSerializer<Pair> {

    public PairSerializer() {
        super();
    }

    @Override
    public JsonElement serialize(final Pair value, final Type type,
            final JsonSerializationContext context) {
        final JsonObject jsonObj = new JsonObject();
        jsonObj.add("first", context.serialize(value.getFirst()));
        jsonObj.add("second", context.serialize(value.getSecond()));

        return jsonObj;
    }
}
如果您发现需要使用适配器,则可以使用嵌入式Gson代理为您序列化对属性,缺点是您无法访问在父Gson代理上进行的自定义注册:

public class PairAdapter extends TypeAdapter<Pair> {
    final Gson embedded = new Gson();

    public PairAdapter() {
        super();
    }

    @Override
    public void write(final JsonWriter out, final Pair value)
            throws IOException {
        out.beginObject();

        out.name("first");
        embedded.toJson(embedded.toJsonTree(value.getFirst()), out);

        out.name("second");
        embedded.toJson(embedded.toJsonTree(value.getSecond()), out);

        out.endObject();
    }

    @Override
    public Pair read(JsonReader in) throws IOException {
        throw new UnsupportedOperationException();
    }
}
public类PairAdapter扩展了TypeAdapter{
最终Gson嵌入=新Gson();
公共PairAdapter(){
超级();
}
@凌驾
公共无效写入(最终JsonWriter out,最终对值)
抛出IOException{
out.beginObject();
名称(“第一”);
embedded.toJson(embedded.toJsonTree(value.getFirst()),out);
名称(“第二”);
embedded.toJson(embedded.toJsonTree(value.getSecond()),out);
out.endObject();
}
@凌驾
公共对读取(JsonReader in)引发IOException{
抛出新的UnsupportedOperationException();
}
}
// With adapter
final Gson gson = new GsonBuilder().registerTypeAdapter(Pair.class,
        new PairAdapter()).create();

// With serializer
final Gson gson = new GsonBuilder().registerTypeAdapter(Pair.class,
        new PairSerializer()).create();
public class PairAdapter extends TypeAdapter<Pair> {
    final Gson embedded = new Gson();

    public PairAdapter() {
        super();
    }

    @Override
    public void write(final JsonWriter out, final Pair value)
            throws IOException {
        out.beginObject();

        out.name("first");
        embedded.toJson(embedded.toJsonTree(value.getFirst()), out);

        out.name("second");
        embedded.toJson(embedded.toJsonTree(value.getSecond()), out);

        out.endObject();
    }

    @Override
    public Pair read(JsonReader in) throws IOException {
        throw new UnsupportedOperationException();
    }
}