2016-11-12 126 views
0

我正尝试反序列化一个JSON成阶类,它包含类型ACLASS,Bclass或Cclass杰克逊反序列化与泛型

class Results[M](results:util.ArrayList[M]) { 

    def getResults:util.ArrayList[M]=results 

    def this() { 
    this(new util.ArrayList()) 
    } 
} 

JSON的样子的集合:

{ "results":[{"a":1},{"a":1}]} 

{ "results":[{"b":1},{"b":1}]} 

{ "results":[{"b":1},{"b":1}]} 

这里我对象映射

val mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 

在这里,我如何反序列化类类型的JSON ACLASS

val results = mapper.readValue(json, classOf[Results[Aclass]]) 

的问题是,结果,返回一个ArrayList中,每一个元素,而不是成为一个实例Aclass,是一个LinkedHashMap

如果我改变代码,而不是使用通用I使其在类型

class Results[Aclass](results:util.ArrayList[Aclass]) { 

    def getResults:util.ArrayList[Aclass]=results 

    def this() { 
    this(new util.ArrayList()) 
    } 
} 

它的工作原理,并与ACLASS元素的数组的结果返回一个类明确。

我在这里做错了什么?我认为这是库中的一个错误

此致。

+0

你坚持与杰克逊或是否也能使用一个库,这不是反射型(例如瑟茜或淘金者)? – Reactormonk

+0

完全打开使用新的库,如果不需要太多的代码,并实现我想要的。但无论如何,我设法使它使用TypeFactory,但仍然不是很高兴我的解决方案看起来多么复杂 – paul

回答

2

原因是java.lang.Class不包含有关通用参数的信息。 classOf[Result[Aclass]]的值是java.lang.Class。它没有关于类型参数Aclass的信息。它仅代表Results类。

该映射器可以做你要求的:给你Results任何东西,最好的是它是一张地图。

要解决该问题,请使用取代JavaType的readValue方法。 JavaType可以使用TypeFactory创建:

val results:Results[Aclass] = mapper.readValue(json, mapper.getTypeFactory() 
     .constructParametricType(classOf[Results[_]], classOf[Aclass])) 
+0

似乎它不能反序列化任何东西。 java.lang.ClassCastException:politrons.apple.search.model.Results不能转换为scala.runtime.Nothing $ – paul

+0

对不起,忘了将类型声明添加到val结果中。没有它,类型被推断为Nothing在运行时显然是不正确的。这是由于readValue方法的此重载的未绑定类型参数。我刚刚更新了答案。 – ondrc

+0

最后,我最终得到另一种解决方案,使用Play json,但谢谢! – paul