【问题标题】:Scala:No suitable constructor found for type [simple type, class Thing]: can not instantiate from JSON objectScala:没有找到适合类型[简单类型,类事物]的构造函数:无法从 JSON 对象实例化
【发布时间】:2016-09-28 00:17:55
【问题描述】:

我曾尝试测试以下代码来读取 Json ,但它是错误的。

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.core.JsonParseException
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.spark.{SparkContext, SparkConf}
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonCreator; 
import java.sql.Date
import java.text.SimpleDateFormat
import org.slf4j.LoggerFactory


@JsonCreator
case class JsonLong{
  @JsonProperty("fdn") var fdn: String = null
  @JsonProperty("type") var tpy: String= null
  @JsonProperty("vid") var vid: String = null
  @JsonProperty("version") var version: String = null
  @JsonProperty("device_id") var device_id: String = null
  @JsonProperty("ip") var ip: String = null
  @JsonProperty("timestamp") var timestamp: Long = 0L
}


def jsonString(logjson:String):JsonLong ={
    val mapper = new ObjectMapper()
    val record = mapper.readValue(logjson, classOf[JsonLong])
    record
  }


val jsoninput = "{\"fdn\":\"FDNB2023750\",\"type\":\"0\",\"vid\":\"2246195\",\"version\":\"1.0\",\"device_id\":\"HM+NOTE+1TD_0c-1d-af-7e-1e-a3_865813020970745\",\"ip\":\"106.118.164.215\",\"timestamp\":1463847764}"


val jsonRDD =   jsonString(jsoninput)

这是我要阅读的 Json: "{\"fdn\":\"FDNB2023750\",\"type\":\"0\",\"vid\":\"2246195\",\"版本\":\"1.0\", \"device_id\":\"HM+NOTE+1TD_0c-1d-af-7e-1e-a3_865813020970745\",\"ip\":\"106.118.164.215\",\"timestamp\":1463847764}"

我收到以下回复: enter image description here

我知道“类型”是 Scala 中的一个关键字。所以,我尝试使用@JsonProperty。是我的代码是对的吗?或者 JsonLong 类还有其他问题吗?

【问题讨论】:

  • 我没有完整的答案,但您可能有 2 个问题。首先,您作为示例提供的 json 包含键“ttype”而不是“type”,因此杰克逊找不到构造函数。其次,my_type 是一个 scala 选项。我不知道 Jackson 是否可以处理这些,因为它是一个 java 库。
  • 对不起,这里没有"ttype",我把"type"改名为"ttpye"只是为了测试~~我把"my_type"改成别的名字了,还是错了~~com.fasterxml.jackson .databind.JsonMappingException:没有找到适合类型[简单类型,类$line45.$read$$iwC$$iwC$JsonLong]的构造函数:无法从JSON对象实例化(需要添加/启用类型信息?)
  • 杰克逊知道如何实例化Option[String]吗?
  • 附带说明,my_type: Option[String] = null 可能不是一个好主意,因为它有点违背使用Option 的目的
  • 但我认为这不是问题~~我尝试 printSchema,它显示 root |-- log_version: string (nullable = true) |-- log_ip: string (nullable = true) |- - log_from: string (nullable = true) |-- SDK: string (nullable = true) |-- action_time: date (nullable = true) |-- action: string (nullable = true) |-- sn: string (nullable = true) |-- post_code: struct (nullable = true) post_code作为struct类型,但不知道里面有什么~~

标签: json scala jackson


【解决方案1】:

我找到了一种处理此日志的方法。但是不要用jackson,用json4s来捕捉key值。

import org.json4s._
import org.json4s.jackson.JsonMethods._

implicit val formats = DefaultFormats 

case class JsonLong(
  var fdn: String=null,
  var `type`: String=null, 
  var vid: String=null,
  var version: String=null,
  var device_id: String=null,
  var ip: String=null,
  var timestamp: Long=0L
)

val jsoninput = "{\"fdn\":\"FDNB2023750\",\"type\":\"0\",\"vid\":\"2246195\",\"version\":\"1.0\",\"device_id\":\"HM+NOTE+1TD_0c-1d-af-7e-1e-a3_865813020970745\",\"ip\":\"106.118.164.215\",\"timestamp\":1463847764}"
val jsontest = parse(jsoninput, useBigDecimalForDouble = true)
    jsontest.extract[JsonLong]

【讨论】:

  • 我听说没有参数case类实际上应该是一个case对象。问题是您需要一个默认构造函数,但是如何将请求绑定到成员,对吗?我现在正试图弄清楚这一点,但我想坚持杰克逊。
猜你喜欢
  • 2011-11-29
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2012-10-06
  • 1970-01-01
相关资源
最近更新 更多