我想将JSON表示为案例类。
{
result:"success" or "fail"
message: "some message"
}
我的特殊要求是result
只应取值“成功”或“错误”。任何其他值都应该无法解析JSON
我尝试创建一个特征,然后对其进行子类化,但我不明白如何限制result
sealed trait JSONResult
case class JSONResultError(final val result:String="error") extends JSONResult
case class JSONResultSuccess(final val result:String="success") extends JSONResult
case class JsonMessages (
result: JSONResult,
message: String
)
虽然我可以创建一个JsonMEssages类型的变量,但我无法区分结果是JSONResultSuccess
还是JSONResultError
。
scala> val jm = JsonMessages(JSONResultError(),"some error message")
jm: JsonMessages = JsonMessages(JSONResultError(error),some error message)
scala>scala> jm.result.result //this doesn't work because result is of type JSONResult which hasn't got `result` though it holds object of type `JSONResultError`
<console>:13: error: value result is not a member of JSONResult
jm.result.result
^
scala> jm.result
res17: JSONResult = JSONResultError(error)
最后,我希望能够创建Reads
或Writes
,但我不相信这会有效。
object JSONMessagesImplicits {
/*Writes (write to JsValue) are used by toJson method of Json object to convert data (say the model) to JsValue*/
implicit val JsonResultErrorWrites: Writes[JSONResultError] = (JsPath \ "result").write[String](unlift(JSONResultError.unapply))
implicit val JsonResultSuccessWrites: Writes[JSONResultSuccess] = (JsPath \ "result").write[String](unlift(JSONResultError.unapply))
implicit val JsonMessagesWithErrorWrites: Writes[JsonMessages] = (
(JsPath \ "result").write[JSONResultError] and
(JsPath \ "message").write[String]) (unlift(JsonMessages.unapply))
implicit val JsonMessagesWithSuccessWrites: Writes[JsonMessages] = (
(JsPath \ "result").write[JSONResultSuccess] and
(JsPath \ "message").write[String]) (unlift(JsonMessages.unapply))
}
答案 0 :(得分:0)
错误消息非常明确:JSONResult
不了解result
字段,因此无法正确序列化。
JSONResult
不一定是trait
,仍然可以将其转换为抽象类,问题应该解决,例如:
sealed abstract class JsonResult(val result: String)
case class JsonResultSuccess(override val result: String = "success") extends JsonResult(result)
case class JsonResultError(override val result: String = "error") extends JsonResult(result)
case class JsonMessage(val result: JsonResult, val message: String)
然后,没有必要为所有内容创建单独的Write
,它可以缩短到这一个:
implicit val resultWrites = new Writes[JsonMessage] {
override def writes(message: JsonMessage) : JsValue = {
Json.obj(
"result" -> message.result.result,
"message" -> message.message
)
}
}
更新
如果您仍然希望/必须使用该方法来定义具有功能语法的Writes
,则仍有一些简化空间。
我认为创建JSONResult
实体只是为了包装&#34;错误&#34;或者&#34;成功&#34;字符串有点过分,当你在原始问题中看到多个Writes
时,它会使进一步的映射变得复杂。
我们可以想象密封的东西如下:
sealed abstract class JsonMessage(val result: String, val message: String)
case class JsonResultSuccess(override val message: String) extends JsonMessage("success", message)
case class JsonResultFailure(override val message: String) extends JsonMessage("failure", message)
是的,message
字段现在与根级result
一起出现; result
值是后代中的常量。
我们还需要实施unapply
JsonMessage
:
object JsonMessage {
def unapply(jsonMessage: JsonMessage): Option[(String, String)] = {
if (jsonMessage == null) None
else Some((jsonMessage.result, jsonMessage.message))
}
}
完成这些更改后,我们只能使用原始样式定义一个Writes
:
implicit val messageWrites: Writes[JsonMessage] =
((JsPath \ "result").write[String] and
(JsPath \ "message").write[String]) (unlift(JsonMessage.unapply))
希望这有帮助。
结束更新