【问题标题】:Parsed JSON values do not match with class constructor解析的 JSON 值与类构造函数不匹配
【发布时间】:2016-01-28 14:23:42
【问题描述】:

我的Runner 代码看起来像

import java.io.File

import org.json4s._
import org.json4s.native.JsonMethods._

object WorkOrderParser {
  implicit val formats = DefaultFormats
  def get(workOrderJson: File): List[WorkOrderItem] = {
    parse(workOrderJson).extract[List[WorkOrderItem]]
  }

  def main(args: Array[String]) {
    println(WorkOrderParser.get(new File("src/main/resources/workConfigSample.json")))
  }
}

我的案例类看起来像

import java.io.File

sealed trait FilePostProcessingAction

case object delete extends FilePostProcessingAction

case object move extends FilePostProcessingAction

case class WorkOrderItem(configName: String,
                         logSource: File,
                         logType: String,
                         afterProcessingFileAction: FilePostProcessingAction,
                         recursiveFind: Option[Boolean] = Some(false),
                         processZipFiles: Option[Boolean] = Some(false))

我的示例 JSON 看起来像

[
  {
    "configName": "bluecoat",
    "logSource": "/root/fw1/logs/bc",
    "logType": "bluecoat",
    "recursiveFind": true,
    "processZipFiles": false,
    "afterProcessingFileAction": "delete"
  },
  {
    "configName": "mcAfee",
    "logSource": "/root/fw1/logs/mcafee",
    "logType": "mcafee",
    "recursiveFind": true,
    "processZipFiles": true,
    "afterProcessingFileAction": "delete"
  }
]

当我运行它时,我得到了

Exception in thread "main" org.json4s.package$MappingException: No usable value for logSource
Parsed JSON values do not match with class constructor
args=
arg types=
constructor=org.json4s.reflect.Executable@1fa268de
    at org.json4s.reflect.package$.fail(package.scala:93)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:509)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$14.apply(Extraction.scala:529)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$14.apply(Extraction.scala:529)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
    at scala.collection.AbstractTraversable.map(Traversable.scala:104)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$instantiate(Extraction.scala:517)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result$6.apply(Extraction.scala:564)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result$6.apply(Extraction.scala:559)
    at org.json4s.Extraction$.org$json4s$Extraction$$customOrElse(Extraction.scala:573)
    at org.json4s.Extraction$ClassInstanceBuilder.result(Extraction.scala:559)
    at org.json4s.Extraction$.extract(Extraction.scala:394)
    at org.json4s.Extraction$CollectionBuilder$$anonfun$6.apply(Extraction.scala:403)
    at org.json4s.Extraction$CollectionBuilder$$anonfun$6.apply(Extraction.scala:403)
    at scala.collection.immutable.List.map(List.scala:273)
    at org.json4s.Extraction$CollectionBuilder.mkCollection(Extraction.scala:403)
    at org.json4s.Extraction$CollectionBuilder.result(Extraction.scala:423)
    at org.json4s.Extraction$.extract(Extraction.scala:377)
    at org.json4s.Extraction$.extract(Extraction.scala:43)
    at org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)
    at com.logprocessor.processor.workOrder.WorkOrderParser$.get(WorkOrderParser.scala:11)
    at com.logprocessor.processor.workOrder.WorkOrderParser$.main(WorkOrderParser.scala:15)
    at com.logprocessor.processor.workOrder.WorkOrderParser.main(WorkOrderParser.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:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.json4s.package$MappingException: Parsed JSON values do not match with class constructor
args=
arg types=
constructor=org.json4s.reflect.Executable@1fa268de
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$instantiate(Extraction.scala:542)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result$6.apply(Extraction.scala:564)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result$6.apply(Extraction.scala:559)
    at org.json4s.Extraction$.org$json4s$Extraction$$customOrElse(Extraction.scala:573)
    at org.json4s.Extraction$ClassInstanceBuilder.result(Extraction.scala:559)
    at org.json4s.Extraction$.extract(Extraction.scala:394)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:497)
    ... 30 more

但是,当我将案例类中的类型更改为 String(对于 logSourceafterProcessingFileAction)时,它可以工作

我做错了什么? 我为此使用https://github.com/json4s/json4s

【问题讨论】:

  • 您可能需要为FileFilePostProcessingAction 定义解析器
  • 我需要扩展解析器吗?
  • 这更可能是隐含的问题。我会看文档

标签: json scala case-class json4s


【解决方案1】:

也许晚了几年,但我看到了 2k 次观看,所以让我们回答这个问题:)

这是因为 json4s 正在寻找如何反序列化 List[WorkOrderItem] 并且找不到匹配 extract[T] 的构造函数,在您的情况下为 extract[List[WorkOrderItem]]。

我相信您需要创建一个自定义反序列化程序并将其注册为支持的格式之一。注意:可能有其他方法可以解决这个问题,例如使用提示或其他功能,但我昨天才开始使用 json4s,所以我有点菜鸟..

例如-

  1. 创建您的案例类 -
case class DynamicStringList(values: List[String]) {
  def show() {
    values.foreach(println)
  }
}
  1. 创建您的序列化程序。下面是一个工作示例 -
case object DynamicStringListSerializer extends CustomSerializer[DynamicStringList] (format => ({
  case JString(stringValue) => DynamicStringList(List(stringValue))
  case JArray(stringValues) => {
    implicit val formats = DefaultFormats
    def jsonJValueToString(jsonString: JValue)(implicit formats: Formats) : String = {
      jsonString.extract[String]
    }
    val dynamicList = stringValues.map(jsonJValueToString).toList
    DynamicStringList(dynamicList) //DynamicStringArray.toArray(stringValues)
  }
}, {
  // TODO - This is the serialize function to JArray, however we will probably never use it so not done for now
  case dynamicList: DynamicStringList => JNothing
}
))
  1. 将此注册为您需要的对象/类中支持的格式 -
import org.json4s.DefaultFormats
import com.myserializers.DynamicStringListSerializer

object MyJSONUtils {   
    implicit val formats = DefaultFormats + DynamicStringListSerializer
  1. 做一些事情(假设您拥有所需的所有其他 json 导入)
parse(json_message_as_string).extract[DynamicStringList]

【讨论】:

    猜你喜欢
    • 2017-12-29
    • 2017-07-18
    • 2018-05-04
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 2019-10-24
    相关资源
    最近更新 更多