java GSON 没有为接口类型调用我的 TypeAdapter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10631250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
GSON not calling my TypeAdapter for a type which is an interface
提问by Trejkaz
GSON appears to be doing some kind of trick where it looks at the internal fields of my JavaBeans instead of using the publically-accessible property information. Unfortunately this won't fly for us because our magically-created beans are full of private fields which I don't want it to store off.
GSON 似乎在做某种伎俩,它查看我的 JavaBeans 的内部字段,而不是使用可公开访问的属性信息。不幸的是,这对我们来说不会成功,因为我们神奇地创建的 bean 充满了我不希望它存储的私有字段。
@Test
public void testJson() throws Exception
{
Player player = new MagicPlayer(); //BeanUtils.createDefault(Player.class);
player.setName("Alice");
Gson gson = new GsonBuilder()
.registerTypeAdapter(Player.class, new PlayerTypeAdapter())
.create();
System.out.println(gson.toJson(bean));
}
private static class PlayerTypeAdapter implements JsonSerializer<Player>
{
@Override
public JsonElement serialize(Player player, Type type,
JsonSerializationContext context)
{
throw new RuntimeException("I got called, woohoo");
}
}
public static interface Player //extends SupportsPropertyChanges
{
public String getName();
public void setName(String name);
}
// Simple implementation simulating what we're doing.
public static class MagicPlayer implements Player
{
private final String privateStuff = "secret";
private String name;
@Override
public String getName()
{
return name;
}
@Override
public void setName(String name)
{
this.name = name;
}
}
This gives:
这给出:
{"privateStuff":"secret","name":"Alice"}
And of course, never calls my type adapter, which seemingly makes it impossible to get any other behaviour.
当然,永远不要调用我的类型适配器,这似乎使得无法获得任何其他行为。
回答by nont
I had the same issue, with version 2.3.1 of Gson. I got it working by using
我有同样的问题,Gson 2.3.1 版。我通过使用它来工作
.registerTypeHierarchyAdapter(Player.class, new PlayerTypeAdapter())
instead of
代替
.registerTypeAdapter(Player.class, new PlayerTypeAdapter())
回答by Eric Schoonover
Current release of GSON does not work this way. This will serialize your type using the adapter.
当前版本的 GSON 不能以这种方式工作。这将使用适配器序列化您的类型。
gson.toJson(bean, Player.class)
gson.toJson(bean, Player.class)
Alternatively you can register the PlayerTypeAdapter
for MagicPlayer.class
and your existing code will work. GSON looks up the TypeAdapter
by the concrete (or top level) type only. So you will have to register a custom type adapter for every concrete type you may encounter.
或者,您可以注册PlayerTypeAdapter
forMagicPlayer.class
并且您现有的代码将起作用。GSON 仅TypeAdapter
按具体(或顶级)类型查找。因此,您必须为可能遇到的每种具体类型注册一个自定义类型适配器。
There is TypeHeirarchyAdapter
for when you want the same TypeAdapter
to be used for all extending classes of a given type. I have not had good luck with this though and have not really spent time looking into why it has not worked well for me. Here is some relevant discussion: https://groups.google.com/forum/?fromgroups=#!searchin/google-gson/interface/google-gson/0ebOxifqwb0/OXSCNTiLpBQJ
还有TypeHeirarchyAdapter
当你想的一样TypeAdapter
用于给定类型的所有扩展类。尽管如此,我的运气并不好,也没有真正花时间研究为什么它对我来说效果不佳。以下是一些相关讨论:https: //groups.google.com/forum/?fromgroups=#!searchin/ google-gson/interface/ google-gson/0ebOxifqwb0/ OXSCNTiLpBQJ
回答by alexey28
Why it does not work:
为什么它不起作用:
PlayerTypeAdapter should implements JsonSerializer. Does it?
If it does - than should work. It work perfect for me, so don't see reason why it does not work for you. Start you application in debug, put breakpoints and checkout. There should be some reason.
PlayerTypeAdapter 应该实现 JsonSerializer。可以?
如果确实如此 - 比应该工作。它对我来说很完美,所以不要明白为什么它对你不起作用。在调试中启动您的应用程序,放置断点并检出。应该是有原因的。
In your test where is Gson builder with adapter? You should change it:
在您的测试中,带有适配器的 Gson 构建器在哪里?你应该改变它:
public void testJson() throws Exception
{
Player player = new MagicPlayer(); //BeanUtils.createDefault(Player.class);
player.setName("Alice");
// this is wrong if you want adapter
/* Gson gson = new Gson(); */
// this is what you nead
Gson gson = new GsonBuilder()
.registerTypeAdapter(Player.class, new PlayerTypeAdapter())
.create();
System.out.println(gson.toJson(bean));
}