找不到类型[simple type,class Definition]的合适构造函数

时间:2017-02-08 13:42:50

标签: java json scala jackson

我使用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"
          }
        }
      ]
    }
  ]
}

2 个答案:

答案 0 :(得分:1)

如果我没有误会,Scala案例类没有无参数构造函数,而是一个构造函数,其中所有字段都作为参数,并且伴随对象的apply方法。但是,Jackson对象映射器需要一个无参数构造函数来首先实例化该类。所以最多"杰克逊"方法是创建一个Java POJO而不是像这里的案例类:Jackson Github

我建议你使用这样的东西: Implicit JSON conversion

另见this answer.

答案 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版本。

相关问题