使用 json 反序列化 java 泛型集合
我正在尝试序列化和反序列化来自 hibernate 的答案。
几乎成功了。
首先,我从数据库获取数据(DealBean 对象)
Collections.checkedList(session.createCriteria(DealBean.class).add(Restrictions.eq("account", account)).list(), DealBean.class);
,然后将其序列化(使用 gson)并将结果发送到客户端。
在客户端中,我尝试使用
Type type = new TypeToken<Collection<DealBean>>(){}.getType();
List<DealBean> dealsForAccount = (List<DealBean>)Json.from(SomeAnswerString);
现在的方法反序列化它 - 我得到 JsonParseException。我认为从hibernate返回的列表是另一种类型java.util.Collections$CheckedRandomAccessList 我得到以下异常(如下)。 1.有什么建议吗? 2.我选择正确吗?我可以在服务器上投射结果吗?
JsonParseException:JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@a17378 无法反序列化 json 对象 {"type":"java.util.Collections$CheckedRandomAccessList","content":"[{\"ID\" :5,\"可交易\":{\"id\":5,\"tradableName\":\"Tradable1\",\"moneyMultiplier\":1},\"操作\":\"购买\" ,\"金额\":501.0,\"价格\":50.3,\"投资组合\":{\"ID\":2,\"投资组合名称\":\"投资组合2\"},\"账户\" :{\"ID\":1,\"账户名称\":\"账户1\",\"银行\":{\"ID\":1,\"银行名称\":\"银行1\"}} ,\"日期\":\"12:17:36 02/01/1970\",\"activitySum\":0.0,\"聚合\":false},{\"ID\":6,\"可交易\":{\"id\":6,\"tradableName\":\"可交易1\",\"资金乘数\":1},\"操作\":\"卖出\",\"金额\ ":1001.0,\"价格\":50.4,\"投资组合\":{\"ID\":2,\"投资组合名称\":\"投资组合2\"},\"帐户\":{\"ID \":2,\"帐户名称\":\"帐户2\",\"银行\":{\"ID\":2,\"银行名称\":\"银行2\"}},\"日期\ ":\"12:17:36 02/01/1970\",\"activitySum\":0.0,\"聚合\":false},{\"ID\":7,\"可交易\":{ \“id\”:7,\“tradableName \”:\“Tradable2 \”,\“moneyMultiplier \”:1},\“操作\”:\“购买\”,\“金额\”:502.0,\ “价格\”:50.5,\“投资组合\”:{\“ID \”:2,\“投资组合名称\”:\“投资组合2 \”},\“帐户\”:{\“ID \”:1, \“帐户名称\”:\“帐户1 \”,\“银行\”:{\“ID \”:1,\“银行名称\”:\“银行1 \”}},\“日期\”:\“12 :17:36 02/01/1970\",\"activitySum\":0.0,\"聚合\":false},{\"ID\":8,\"可交易\":{\"id\" :8,\"tradableName\":\"Tradable2\",\"moneyMultiplier\":1},\"Action\":\"sell\",\"amount\":1002.0,\"price\": 50.6,\"投资组合\":{\"ID\":2,\"投资组合名称\":\"投资组合2\"},\"账户\":{\"ID\":2,\"账户名称\" :\"帐户2\",\"银行\":{\"ID\":2,\"银行名称\":\"银行2\"}},\"日期\":\"12:17:36 02 /01/1970\",\"activitySum\":0.0,\"aggregate\":false}]"} 给定类型 java.util.Collection 在com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:63) 在 com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:88) 在 com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:76) 在 com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:98) 在 com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:73) 在com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:51) 在 com.google.gson.Gson.fromJson(Gson.java:495) 在 com.google.gson.Gson.fromJson(Gson.java:444) 在 com.google.gson.Gson.fromJson(Gson.java:396) 在positions.server.services.PositionServerServicesInternalWrapperTest.testGetPositionsForPortfolio(PositionServerServicesInternalWrapperTest.java:134) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 在 org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:236) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:157) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65) 引起原因:java.lang.IllegalStateException:这不是 JSON 数组。 在 com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:100) 在 com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:468) 在 com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:435) 在com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:50) ... 31 更多
List<BankBean> al = new ArrayList<BankBean>();
al.add(bank1);
al.add(bank2);
String alStr = Json.toWrap(al); //
List<BankBean> reAl;
Gson gson = new Gson();
Type type = new TypeToken<Collection<BankBean>>(){}.getType();
List<String> listFromJson = gson.fromJson(alStr,type);
I am trying to serialize and dederialize an answer from hibernate.
almost successfully.
First I get the data (object DealBean) from the DB using
Collections.checkedList(session.createCriteria(DealBean.class).add(Restrictions.eq("account", account)).list(), DealBean.class);
then I serialize it (using gson) and send the result to the client.
in the client I try to deserialize it using
Type type = new TypeToken<Collection<DealBean>>(){}.getType();
List<DealBean> dealsForAccount = (List<DealBean>)Json.from(SomeAnswerString);
now - I get JsonParseException. I think that the list returned from the hibernate is another type java.util.Collections$CheckedRandomAccessList
I get the following exception (below).
1. any suggestions?
2. am i selecting correctly ? could i cast the result at the server ?
JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@a17378 failed to deserialized json object {"type":"java.util.Collections$CheckedRandomAccessList","content":"[{\"ID\":5,\"tradable\":{\"id\":5,\"tradableName\":\"Tradable1\",\"moneyMultiplier\":1},\"Action\":\"buy\",\"amount\":501.0,\"price\":50.3,\"portfolio\":{\"ID\":2,\"portfolioName\":\"Portfolio2\"},\"account\":{\"ID\":1,\"accountName\":\"Account1\",\"bank\":{\"ID\":1,\"BankName\":\"Bank1\"}},\"date\":\"12:17:36 02/01/1970\",\"activitySum\":0.0,\"aggregated\":false},{\"ID\":6,\"tradable\":{\"id\":6,\"tradableName\":\"Tradable1\",\"moneyMultiplier\":1},\"Action\":\"sell\",\"amount\":1001.0,\"price\":50.4,\"portfolio\":{\"ID\":2,\"portfolioName\":\"Portfolio2\"},\"account\":{\"ID\":2,\"accountName\":\"Account2\",\"bank\":{\"ID\":2,\"BankName\":\"Bank2\"}},\"date\":\"12:17:36 02/01/1970\",\"activitySum\":0.0,\"aggregated\":false},{\"ID\":7,\"tradable\":{\"id\":7,\"tradableName\":\"Tradable2\",\"moneyMultiplier\":1},\"Action\":\"buy\",\"amount\":502.0,\"price\":50.5,\"portfolio\":{\"ID\":2,\"portfolioName\":\"Portfolio2\"},\"account\":{\"ID\":1,\"accountName\":\"Account1\",\"bank\":{\"ID\":1,\"BankName\":\"Bank1\"}},\"date\":\"12:17:36 02/01/1970\",\"activitySum\":0.0,\"aggregated\":false},{\"ID\":8,\"tradable\":{\"id\":8,\"tradableName\":\"Tradable2\",\"moneyMultiplier\":1},\"Action\":\"sell\",\"amount\":1002.0,\"price\":50.6,\"portfolio\":{\"ID\":2,\"portfolioName\":\"Portfolio2\"},\"account\":{\"ID\":2,\"accountName\":\"Account2\",\"bank\":{\"ID\":2,\"BankName\":\"Bank2\"}},\"date\":\"12:17:36 02/01/1970\",\"activitySum\":0.0,\"aggregated\":false}]"} given the type java.util.Collection
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:63)
at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:88)
at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:76)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:98)
at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:73)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:51)
at com.google.gson.Gson.fromJson(Gson.java:495)
at com.google.gson.Gson.fromJson(Gson.java:444)
at com.google.gson.Gson.fromJson(Gson.java:396)
at positions.server.services.PositionServerServicesInternalWrapperTest.testGetPositionsForPortfolio(PositionServerServicesInternalWrapperTest.java:134)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
Caused by: java.lang.IllegalStateException: This is not a JSON Array.
at com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:100)
at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:468)
at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:435)
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:50)
... 31 more
List<BankBean> al = new ArrayList<BankBean>();
al.add(bank1);
al.add(bank2);
String alStr = Json.toWrap(al); //
List<BankBean> reAl;
Gson gson = new Gson();
Type type = new TypeToken<Collection<BankBean>>(){}.getType();
List<String> listFromJson = gson.fromJson(alStr,type);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
类型 java.util.Collections$CheckedRandomAccessList 是由
Collections.checkedList
另一个列表,确保将任何内容添加到列表匹配适当的类型签名。除非您有某种方法指定如何创建支持列表和它应该检查的类型(又名 java.lang.Class 的实例),否则有没有足够的信息来构建一个。要修复此问题,可以将
"java.util.Collections$CheckedRandomAccessList"
更改为"java.util.ArrayList"
并调用Collections.checkedList
使用适当的保护类型进行反序列化的结果。为了防止问题再次出现,如果您的列表不是 ArrayList 实例,则可以在序列化之前执行以下操作:
The type
java.util.Collections$CheckedRandomAccessList
is a wrapper produced byCollections.checkedList
of another list that makes sure that anything added to the list matches the appropriate type signature. Unless you have some way of specifying how to create the backing list and the type (aka instance ofjava.lang.Class
) that it is supposed to check, then there is not enough information to construct one.To fix it, maybe change
"java.util.Collections$CheckedRandomAccessList"
to"java.util.ArrayList"
and callCollections.checkedList
on the result of your deserialization with the appropriate guard type.And to prevent the problem from recurring, maybe do the following before serializing if your list is not an
instanceof ArrayList<?>
:您拥有的 JSON 看起来不像简单的集合,而是像具有属性和集合的 bean。所以这可能需要改变。
无论使用哪个库,您的 JSON 都必须与您要映射到的对象匹配。
如果您无法使其与 Gson 一起使用,您可以尝试其他具有更强大数据绑定功能的工具。
JSON you have does not look like simple collection, but rather like a bean that has properties and collection. So that may need to be changed.
Your JSON must match object(s) you are mapping to, regardless of library being used.
And if you can't make it work with Gson, there are others you can try out, with more powerful data binding featuers.