scalajson:解析可选值(默认值)无选项



我想解析Json文件以读取可能提供的值。如果没有提供,我有默认值 fallaf back on。

显然在这种情况下,最终结果是我肯定会有一个值:从Json读取或默认值。但是,根据我目前对ScalaJson的了解(如果我错了,请纠正我(,我仍然必须使用Option[T]来持有它(因为它可能直接在Json文件中可用(。换句话说,我相信虽然我可以提供默认值,但仍必须包裹在Option[T]

有没有一种方法可以读取可选 value(使用默认(,而无需 wrap Option[T]中?我想事先告知我不需要(在可预见的将来(写( serialize (我的数据到Json中,我只需要阅读(deserialize(Json。bk_hr>

进一步阐述我的问题: -

我正在使用自动转换使用case class ES,因此,不必将此case class与给定的reads converter

一起使用
case class MyCaseClass(optString: Option[String] = Some("None"))
implicit val reads = Json.reads[MyCaseClass]

我想使用此case class

case class MyCaseClass(optStringWithDefault: String = "None")

是否可以给出相同的Json源为此case class编写read converter?另外,是否有更好的设计选择可以完全克服这个问题?


我在

  • Scala 2.11.11
  • PlayFramework 2.6

如果您使用SBT,则可以在项目中包含

的spray-json
libraryDependencies += "io.spray" %%  "spray-json" % "1.3.3"

定义案例类

case class MyCaseClass(optString: String = "None")

定义JSON转换的协议。

import spray.json._
object MyProtocol extends DefaultJsonProtocol {
    implicit object MyCaseClassFormat extends RootJsonFormat[MyCaseClass] {
      def write(obj: MyCaseClass): JsValue = JsObject(
        "optString" -> JsString(obj.optString)
      )
      def read(json: JsValue): MyCaseClass = {
        json.asJsObject.getFields("optString") match {
          case Seq(JsString(optString)) => MyCaseClass(optString.asInstanceOf[String])
          case _ => MyCaseClass()
        }
      }
    }
  }

导入协议

import MyProtocol._

方案1#

import spray.json._
val jsonStringOne: String = """{"optString": "testData"}"""
val resultOne = jsonStringOne.parseJson.convertTo[MyCaseClass]
Output: MyCaseClass(testData)

方案2#

import spray.json._
val jsonStringTwo: String = """{"otherString": "tempData"}"""
val resultTwo = jsonStringTwo.parseJson.convertTo[MyCaseClass]
Output: MyCaseClass(None)

参考链接:https://github.com/spray/spray-json

使用jsoniter-scala,它具有内置的支持案例类字段的默认值。

添加库依赖关系:

libraryDependencies ++= Seq(
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "0.29.2" % Compile, 
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "0.29.2" % Provided // required only in compile-time
)

生成用于根类型的编解码器,并将其用于解析具有默认值的案例类:

import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._
case class Device(id: Int = 1, model: String = "iPhone X")
case class User(name: String = "Joe", devices: Seq[Device] = Seq(Device()))
implicit val codec: JsonValueCodec[User] = JsonCodecMaker.make[User](CodecMakerConfig())
val user = readFromArray("{}".getBytes)
require(user == User())

最新更新