使用SprayJson Scala解析n选项[List[Object]]

wfveoks0  于 2022-11-29  发布在  Scala
关注(0)|答案(1)|浏览(126)

遇到了一些Json的怪癖。我正在为一个传入的请求编写串行化-反串行化逻辑,该请求包含一个JSON形式的对象,即IndividualObject。我正在使用Spray Json进行此操作。尝试使用 toVector、Map项列表来解决以下问题,但无法解决类型不匹配问题。

case class IndividualObject(id: String, path: String)
object IndividualObjectJson extends DefaultJsonProtocol {
    implicit val individualObjectFormat = jsonFormat2(IndividualObject.apply)
}

case class IncomingRequest(anotherId: String, indivObjects: Option[List[IndividualObject]])
trait IncomingRequestJson extends SprayJsonSupport with DefaultJsonProtocol {
    implici val incomingRequestFormat: RootJsonFormat[IncomingRequest] = new RootJsonFormat[IncomingRequest] {
        override def read(json: JsValue): IncomingRequest = {
            val fields = json.asJsObject.fields
            IncomingRequest(
                anotherId = fields("anotherId").convertTo[String]
                indivObjects = fields("indivObjects").convertTo[Option[List[IndividualObject]]]
            )
         override def write(obj: IncomingRequest): JsValue = {
             val jsBuilder = Map.newBuilder[String,JsValue]
             jsBuilder += "anotherId" -> JsString(obj.anotherId)
             jsBuilder += "indivObjects" -> JsArray(obj.indivObjects.get map (IndividualObjectJson.individualObjectFormat))
             JsObject(jsBuilder.result())
         }

在JsArray行中发现以下错误:jsBuilder +=“独立对象”-〉JsArray(对象.独立对象.获取Map(独立对象.独立对象格式))

Error: type mismatch
    found: spray.json.RootJsonFormat[IndividualObject]
    required: List[IndividualObject]

任何帮助都是感谢理解为什么它不能解析选项[列表[....]]反序列化。谢谢

sigwle7e

sigwle7e1#

您可以使用jsonFormat 2为具有两个参数的case类创建默认的json读取器/写入器。编译器将通过隐式解析注入代码以处理这些参数。但这不是JsValue(JsString,JsObject,....)。如果您创建自己的Json编码器/编码器,则必须手动包含JsValue示例以创建最终的JsValue。类似如下:

override def write(obj: IncomingRequest): JsValue = {
    val jsBuilder = Map.newBuilder[String, JsValue]
    jsBuilder += "anotherId" -> JsString(obj.anotherId)
    jsBuilder += "indivObjects" -> JsArray({
    obj.indivObjects match {
        case Some(list) =>
          list
            .map(el =>
              JsObject(
                Map("id" -> JsString(el.id), "path" -> JsString(el.path))
              )
            )
            .toVector
        case None => Vector.empty
      }
    })
    JsObject(jsBuilder.result())
  }

这样的东西应该可以编译。

相关问题