我想解析User
文件以读取可能选择提供的值。如果没有提供,我有默认值以便重新开始。
显然,在这种情况下,最终结果是我肯定会有一个值:从uid
读取的那个或默认值。但是根据我目前对ScalaJson
的了解(如果我错了请纠正我),我仍然需要使用Json
来保留它(因为它可能无法直接在{ {1}}文件)。换句话说,我相信虽然我可以提供默认值,但它仍然必须包含在Json
有没有办法读取可选值(默认),而不必在Option[T]
内包裹?我想提前通知我(在可预见的将来)没有要求(序列化)将我的数据写入Json
,我只需要阅读它({{1 }})Option[T]
。
进一步阐述我的问题: -
我正在使用automatic-conversion using case class
es,因此不必将此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
答案 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)
答案 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())