我似乎能够使用Jackson制作Json-String的映射器 - > scala.collection.Map。
如何将同一个映射器连接到RestTemplate?
val restTemplate = new RestTemplate()
val module = new OptionModule with MapModule with SeqModule with IteratorModule
val mapper = new ObjectMapper()
mapper.registerModule(module)
// Get some example JSON
val uri = "http://...."
val response:String = restTemplate.getForObject(uri, classOf[String] )
// *** success ***
// Use the mapper directly: String --> scala.collection.Map
val map1 = mapper.readValue(response, classOf[scala.collection.Map[String, Any]])
// Try hooking up the same module to the RestTemplate:
val wrappingConverter = new WrappingHttpMessageConverter()
wrappingConverter.getObjectMapper().registerModule(module)
val list = restTemplate.getMessageConverters()
list.add(wrappingConverter)
restTemplate.setMessageConverters(list)
// *** FAILS ***
// org.springframework.http.converter.HttpMessageNotReadableException: Could not read
// JSON: Can not construct instance of scala.collection.Map, problem: abstract types
// either need to be mapped to concrete types, have custom deserializer, or be
// instantiated with additional type information
val map2 = restTemplate.getForObject(uri, classOf[scala.collection.Map[String, Any]] )
答案 0 :(得分:3)
WrappingHttpMessageConverter
是MappingJackson2HttpMessageConverter
的派生类,或类似的类。默认的RestTemplate
构造函数会尝试检测Jackson是否在您的类路径中,如果是,则将MappingJackson2HttpMessageConverter
添加到MessageConverters
列表中。由于它已经在列表中,因此将在您WrappingHttpMessageConverter
被检查之前使用它。
该默认转换器没有安装Scala模块。事情变得棘手。 HttpMessageConverterExtractor
尝试询问第一个转换器是否可以反序列化该类型;目前ObjectMapper为此测试返回true
( 是否应该是一个更长的主题,不像它看起来那么明确)。提取器不处理一个转换器可能失败的想法,但后一个转换器可能会成功(就像你的情况一样)。
你需要确保Spring在尝试使用Scala模块之前找到一个配置了它的ObjectMapper。你可以通过多种方式做到这一点;最强大的是搜索预先配置的转换器并更新您找到的第一个转换器,如果您找不到,则添加一个新转换器:
val jacksonConverter = list.asScala.collectFirst {
case p: MappingJackson2HttpMessageConverter => p
}
if (jacksonConverter.isDefined) {
jacksonConverter.get.getObjectMapper.registerModule(module)
}
else {
list.add(new MappingJackson2HttpMessageConverter) // or your derived class if you prefer
}
其他选项包括将自定义消息转换器添加到列表的前面,或者在添加自己的Jackson转换器之前将其删除。