org.json4s.package$MappingException: 无法转换 JObject



这是我的case class

case class WorkOrderItem(configName: String,
                         logSource: File,
                         logType: String,
                         afterProcessingFileAction: String,
                         recursiveFind: Boolean = false,
                         processZipFiles: Boolean = 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"
  }
]

我编写了一个自定义序列化程序

class FileSerializer extends CustomSerializer[WorkOrderItem](format => ( {
    case JObject(JField("configName", JString(configName)) ::
      JField("logSource", JString(logSource)) ::
      JField("logType", JString(logType)) ::
      JField("afterProcessingFileAction", JString(afterProcessingFileAction)) ::
      JField("recursiveFind", JBool(recursiveFind)) ::
      JField("processZipFiles", JBool(processZipFiles)) ::
      Nil) =>
      new WorkOrderItem(configName, new File(logSource), logType, afterProcessingFileAction, recursiveFind, processZipFiles)
  }, {
    case x: WorkOrderItem => ???
  }
    ))

当我运行它时

object WorkOrderParser {
  class FileSerializer extends CustomSerializer[WorkOrderItem](format => ( {
    case JObject(JField("configName", JString(configName)) ::
      JField("logSource", JString(logSource)) ::
      JField("logType", JString(logType)) ::
      JField("afterProcessingFileAction", JString(afterProcessingFileAction)) ::
      JField("recursiveFind", JBool(recursiveFind)) ::
      JField("processZipFiles", JBool(processZipFiles)) ::
      Nil) =>
      new WorkOrderItem(configName, new File(logSource), logType, afterProcessingFileAction, recursiveFind, processZipFiles)
  }, {
    case x: WorkOrderItem => ???
  }
    ))

  implicit val formats = Serialization.formats(NoTypeHints) + new FileSerializer
  def get(workOrderJson: File): List[WorkOrderItem] = {
    parse(workOrderJson).extract[List[WorkOrderItem]]
  }
  def main(args: Array[String]) {
    val items: List[WorkOrderItem] = WorkOrderParser.get(new File("resources/workConfigSample.json"))
    items.foreach((x: WorkOrderItem) => println(x.afterProcessingFileAction))
  }
}

我收到错误,因为

Exception in thread "main" org.json4s.package$MappingException: Can't convert JObject(List((configName,JString(bluecoat)), (logSource,JString(/root/fw1/logs/bc)), (logType,JString(bluecoat)), (recursiveFind,JBool(true)), (processZipFiles,JBool(false)), (afterProcessingFileAction,JString(delete)))) to class com.logprocessor.processor.workOrder.WorkOrderItem
    at org.json4s.CustomSerializer$$anonfun$deserialize$1.applyOrElse(Formats.scala:385)
    at org.json4s.CustomSerializer$$anonfun$deserialize$1.applyOrElse(Formats.scala:382)
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
    at scala.PartialFunction$class.applyOrElse(PartialFunction.scala:123)
    at scala.collection.AbstractMap.applyOrElse(Map.scala:59)
    at scala.PartialFunction$OrElse.apply(PartialFunction.scala:167)
    at org.json4s.Extraction$.org$json4s$Extraction$$customOrElse(Extraction.scala:572)
    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:29)
    at com.logprocessor.processor.workOrder.WorkOrderParser$.main(WorkOrderParser.scala:33)
    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)

我在这里做错了什么?

发生这种情况是因为违反了字段的顺序。

我遇到了同样的问题,您可以使用一种解决方法来防止 json 的顺序很重要。毕竟 json 是非结构化数据,因此最好能够通过将自定义序列化程序替换为以下内容来按任何顺序处理对象属性:

import org.json4s.CustomSerializer
import org.json4s.JsonAST._
import org.json4s.JsonDSL._

class WorkOrderItemSerializerUnordered extends CustomSerializer[WorkOrderItem](format => ( {
  case jsonObj: JObject =>
    val configName = (jsonObj  "configName").extract[String]
    val logSource = (jsonObj  "logSource").extract[String]
    val logType = (jsonObj  "logType").extract[String]
    val afterProcessingFileAction = (jsonObj  "afterProcessingFileAction").extract[String]
    val recursiveFind = (jsonObj  "recursiveFind").extract[Boolean]
    val processZipFiles = (jsonObj  "processZipFiles").extract[Boolean]
    new WorkOrderItem(configName, new File(logSource), logType, afterProcessingFileAction, recursiveFind, processZipFiles)
}, {
  case wi: WorkOrderItem =>
    ("configName" -> wi.configName) ~
      ("logSource" -> wi.logSource) ~
      ("logType" -> wi.logType) ~
      ("afterProcessingFileAction" -> wi. afterProcessingFileAction) ~
      ("recursiveFind" -> wi.recursiveFind) ~
      ("processZipFiles" -> wi.processZipFiles) 
}
))

这是我在以下位置找到此建议的链接:https://nmatpt.com/blog/2017/01/29/json4s-custom-serializer/

相关内容

最新更新