首页 > 解决方案 > Spray-json 和缺少定义的 json writer

问题描述

我是 Scala 的新手,也许这个问题很容易解决,但我很难理解为什么会出现编译错误。

所以我有我的案例课程

case class AggregationQuery  (
  startDate: String,
  endDate: String,
  aggregates: Aggregates,
  value: Value,
  options: Options   
)

case class Aggregates (aggregate: List[String])
case class Options (excludePredicted: Boolean,excludeZeroMetricValue: Boolean)
case class Value (name: String,metric: String,parameters: Parameters)
case class Parameters (numberFormat: String,bigNumberFormat: String,currency: String)

对于我为 RootJsonFormat 创建的每个扩展

object OptionsProtocol {
  implicit object optionValue extends RootJsonFormat[Options] {
    def write(option: Options): JsValue = {
      JsObject(
        "excludePredicted" -> option.excludePredicted.toJson,
        "excludeZeroMetricValue" -> option.excludeZeroMetricValue.toJson
      )
    }
    override def read(json: JsValue): Options = ???
  }
}

object ValueProtocol {
  implicit object parametersValue extends  RootJsonFormat[Value] {
    def write(value: Value): JsValue = {
      JsObject(
        "metric" -> value.metric.toJson,
        "name" -> value.name.toJson,
        "paramters" -> value.parameters.toJson
      ).toJson
    }

    override def read(json: JsValue) = ???
  }
}

object AggregatesProtocol  {
  implicit object optionValue extends RootJsonFormat[Aggregates] {
    def write(aggregate: Aggregates): JsValue = {
      val list= aggregate.aggregate
      JsObject( "aggregates" ->list.toJson )
     }
    override def read(json: JsValue): Aggregates = ???
  }}

然后我又添加了一个 RootJsonFormat 我假设它将聚合上述格式化程序

object AggregateQueryProtocol  {
    implicit object  aggregateQueryValue extends  RootJsonFormat[AggregationQuery] {
      def write(query: AggregationQuery): JsValue = {
        JsObject(
          "startDate" -> query.startDate.toJson,
          "endDate" -> query.endDate.toJson,
         "aggregates" -> query.aggregates.toJson,
          "value" -> query.value.toJson,
          "options" -> query.options.toJson
        )
      }
      override def read(json: JsValue): AggregationQuery = ???
    }
}

现在我想创建我的 AggregationQuery json

AggregationQuery(
  dateRange.startDate,
  dateRange.endDate,
  filters,
  aggregates,
  value,
  option
).toJson;

但是我有没有定义 jsonwriter 的聚合和选项的编译错误,

Error:(23, 43) not enough arguments for method toJson: (implicit writer: spray.json.JsonWriter[aggreagateQuery.Aggregates])spray.json.JsValue.
Unspecified value parameter writer.
         "aggregates" -> query.aggregates.toJson,
Error:(23, 43) Cannot find JsonWriter or JsonFormat type class for aggreagateQuery.Aggregates
         "aggregates" -> query.aggregates.toJson,

我不知道我做错了什么,添加了所有导入。这也很奇怪,因为 Value 类没有错误。基本上,这些类非常相似,放在同一个包中:/

也许有人可以给我一些提示?

问候卢卡斯

标签: scalaspray-json

解决方案


这是对我有用的代码:

import spray.json.DefaultJsonProtocol._
import spray.json.{JsObject, JsValue, RootJsonFormat, _}

object Main extends App {

  case class AggregationQuery(startDate: String,
                           endDate: String,
                           aggregates: Aggregates,
                           value: Value,
                           options: Options)



case class Aggregates(aggregate: List[String])

  case class Options(excludePredicted: Boolean, excludeZeroMetricValue: Boolean)

  case class Parameters(numberFormat: String, bigNumberFormat: String, currency: String)

  case class Value(name: String, metric: String, parameters: Parameters)


  implicit object optionsFormat extends RootJsonFormat[Options] {
    def write(option: Options): JsValue = {


    JsObject(
        "excludePredicted" -> option.excludePredicted.toJson,
        "excludeZeroMetricValue" -> option.excludeZeroMetricValue.toJson
      )
    }

    override def read(json: JsValue): Options = Options(excludePredicted = true, excludeZeroMetricValue = false)
  }


  implicit object parametersFormat extends RootJsonFormat[Parameters] {
    def write(parameters: Parameters): JsValue = {
      JsObject(
        "numberFormat" -> parameters.numberFormat.toJson,
        "bigNumberFormat" -> parameters.bigNumberFormat.toJson,
        "currency" -> parameters.currency.toJson
      )
    }

    override def read(json: JsValue): Parameters = Parameters("", "", "")
  }


  implicit object valueFormat extends RootJsonFormat[Value] {
    def write(value: Value): JsValue = {
      JsObject(
        "metric" -> value.metric.toJson,
        "name" -> value.name.toJson,
        "paramters" -> value.parameters.toJson
      ).toJson
    }

    override def read(json: JsValue) = Value("", "", Parameters("", "", ""))
  }


  implicit object aggregatesValue extends RootJsonFormat[Aggregates] {
    def write(aggregate: Aggregates): JsValue = {
      val list = aggregate.aggregate
      JsObject("aggregates" -> list.toJson)
    }

    override def read(json: JsValue): Aggregates = Aggregates(List())
  }


  implicit object aggregateQueryValue extends RootJsonFormat[AggregationQuery] {
    def write(query: AggregationQuery): JsValue = {
      JsObject(
        "startDate" -> query.startDate.toJson,
        "endDate" -> query.endDate.toJson,
        "aggregates" -> query.aggregates.toJson,
        "value" -> query.value.toJson,
        "options" -> query.options.toJson
      )
    }

    override def read(json: JsValue): AggregationQuery =
      AggregationQuery("", "", Aggregates(List()), Value("", "", Parameters("", "", "")), Options(excludePredicted = true, excludeZeroMetricValue = false))
  }


  AggregationQuery("2016", "2018", Aggregates(List()), Value("", "", Parameters("", "", "")), Options(excludePredicted = true, excludeZeroMetricValue = false)).toJson

}

我基本上添加了 parametersFormat 并删除了包裹在格式化程序周围的对象。

希望这可以帮助。


推荐阅读