ScalaJson:在没有Option的情况下解析可选值(默认值)

时间:2018-02-26 12:49:13

标签: scala playframework play-json

我想解析User文件以读取可能选择提供的值。如果没有提供,我有默认值以便重新开始。

显然,在这种情况下,最终结果是我肯定会有一个值:从uid读取的那个或默认值。但是根据我目前对ScalaJson的了解(如果我错了请纠正我),我仍然需要使用Json来保留它(因为它可能无法直接在{ {1}}文件)。换句话说,我相信虽然我可以提供默认值,但它仍然必须包含在Json

有没有办法读取可选值(默认),而不必在Option[T]包裹?我想提前通知我(在可预见的将来)没有要求(序列化)将我的数据写入Json,我只需要阅读它({{1 }})Option[T]

进一步阐述我的问题: -

我正在使用automatic-conversion using case classes,因此不必将此Option[T]用于给定的Json deserialize

Json

我想使用此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")
  • read converter

2 个答案:

答案 0 :(得分:0)

如果你使用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

答案 1 :(得分:0)

使用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())