我使用Jackson框架编写了一个Scala程序来读取Json文件。执行Scala程序时,我收到以下错误。任何人都可以建议我如何克服这个错误。
错误
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class Definition]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: { "recordDefinitions": [ { "recordDefinitionIdentifier": 2, "recordTypeCode": "LT", "recordTypePattern": "^.{14}LT.*$", "minimumNumberOfAttributes": 19, "expectedNumberOfAttributes": 19, "recordLength": 117, "attributes": [ { "attributeIdentifier": 1, "attributeName": "PROVIDER TYPE", "attributeMaximumLength": 1, "datatype": { "datatypeName": "AN" } } ] } ]}; line: 1, column: 4]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1071)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:264)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2161)
at Json_Parser_Jackson$.main(Json_Parser_Jackson.scala:33)
at Json_Parser_Jackson.main(Json_Parser_Jackson.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
程序
import java.io.{File, StringWriter}
import java.util
import com.fasterxml.jackson.core.`type`.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.apache.avro.ipc.specific.Person
import scala.io.Source
case class Definition(recordDefinitions: Seq[RecordDefinitionsClass])
case class RecordDefinitionsClass(recordDefinitionIdentifier:Int,recordTypeCode: String,recordTypePattern:String,minimumNumberOfAttributes: Int,expectedNumberOfAttributes: Int,recordLength:Int,attributes: Seq[Attributes])
case class Attributes(attributeIdentifier: Int,attributeName:String,attributeMaximumLength:Int,datatype: Seq[DataType])
case class DataType(datatypeName:String)
object Json_Parser_Jackson {
def main(args: Array[String]): Unit = {
val fileContent = Source.fromFile("C:\\Users\\xxxnd\\ideaProject\\jsonparser\\src\\main\\resources\\Json_file.json","UTF-8").getLines.mkString
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val person2: Definition = new ObjectMapper().readValue(fileContent,classOf[Definition])
println(person2)
}
}
Json文件
{
"recordDefinitions": [
{
"recordDefinitionIdentifier": 2,
"recordTypeCode": "LT",
"recordTypePattern": "^.{14}LT.*$",
"minimumNumberOfAttributes": 19,
"expectedNumberOfAttributes": 19,
"recordLength": 117,
"attributes": [
{
"attributeIdentifier": 1,
"attributeName": "PROVIDER TYPE",
"attributeMaximumLength": 1,
"datatype": {
"datatypeName": "AN"
}
}
]
}
]
}
答案 0 :(得分:1)
如果我没有误会,Scala案例类没有无参数构造函数,而是一个构造函数,其中所有字段都作为参数,并且伴随对象的apply
方法。但是,Jackson对象映射器需要一个无参数构造函数来首先实例化该类。所以最多"杰克逊"方法是创建一个Java POJO而不是像这里的案例类:Jackson Github
我建议你使用这样的东西: Implicit JSON conversion
答案 1 :(得分:1)
要阐明具体的解决方案并节省一些时间,这是我发现的最好方法:
case class MyData(@JsonProperty("myStringVar") myStringVar: String,
@JsonProperty("my_renamed_var") myRenamedVar: Int)
NB。在Jackson 3.x [0]以下,即使不重命名,也需要在注释中重复变量名称。在这种情况下,您可以考虑包含jackson-modules-java8,应该可以简单地添加@JsonProperty
注释。
如果您喜欢纯Scala方法,还可以添加一个空的构造函数和@BeanProperty
批注。
[0],例如AWS Lambda Java SDK当前需要的jackson-databind 2.6.7.1版本。