开发者

Deserialize java generics collection with json

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.fromJso开发者_开发百科n(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);


The type java.util.Collections$CheckedRandomAccessList is a wrapper produced by Collections.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 of java.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 call Collections.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<?>:

List<Object> mySerializableList = new ArrayList<Object>(myList);


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜