Scala Json.writes用于密封特性

Scala Json.writes用于密封特性,scala,play-json,Scala,Play Json,如何反序列化一个密封的特征。我正在使用play JSON框架。我已经读了很多写同伴对象的帖子。有人知道如何为Json.writes编写代码吗 sealed trait DataFormat case object JSON extends DataFormat case object INVALID extends DataFormat 如中所示,可以使用Json生成密封族(密封特征和子类型)的读取/OWrites/实例。{

如何反序列化一个密封的特征。我正在使用play JSON框架。我已经读了很多写同伴对象的帖子。有人知道如何为Json.writes编写代码吗

sealed trait DataFormat             
case object JSON extends DataFormat                      
case object INVALID extends DataFormat
如中所示,可以使用Json生成密封族(密封特征和子类型)的
读取
/
OWrites
/
实例。{read,write,format}

import play.api.libs.json._

sealed trait DataFormat
case object JsonFormat extends DataFormat
case object InvalidFormat extends DataFormat

object DataFormat {
  implicit val format: OFormat[DataFormat] = {
    implicit def jsf = Json.format[JsonFormat.type]
    implicit def ivf = Json.format[InvalidFormat.type]

    Json.format[DataFormat]
  }
}
请使用,不要命名类型(大写的类、对象、特征)

然后:

你可以看看这些限制

您还可以查看一下(将枚举类型与Play JSON一起使用)


关于注释中的备选代码:

因此存在错误的命名,不需要
val dataFormatWrites

如果您想在Play JSON中表示枚举类型,我强烈建议您查看前面提到的Enumeratum Play JSON。 无论如何,它可以通过编写已经提供的
读取[String]
写入[String]
实例来完成

import play.api.libs.json._

sealed trait DataFormat
case object JsonFormat extends DataFormat
case object InvalidFormat extends DataFormat

object DataFormat {
  implicit def writes: Writes[DataFormat] =
    implicitly[Writes[String]]. // Resolve default `Writes[String]`
      contramap[DataFormat] {
        case JsonFormat => "JSON"
        case _ => "INVALID"
      }

  implicit def reads: Reads[DataFormat] =
    implicitly[Reads[String]]. // Resolve default `Reads[String]`
      collect[DataFormat](JsonValidationError("Unsupported DataFormat")) {
        case "JSON" => JsonFormat
        case _ => InvalidFormat
      }
}

scala> Json.toJson[DataFormat](JsonFormat)
res1: play.api.libs.json.JsValue = "JSON"

scala> Json.toJson(InvalidFormat: DataFormat)
res3: play.api.libs.json.JsValue = "INVALID"

scala> JsString("JSON").validate[DataFormat]
res4: play.api.libs.json.JsResult[DataFormat] = JsSuccess(JsonFormat,)

scala> JsString("INVALID").validate[DataFormat]
res5: play.api.libs.json.JsResult[DataFormat] = JsSuccess(InvalidFormat,)
此外,我不会定义
case object InvalidFormat
,因为它不表示格式,而是在尝试使用支持的格式时出现错误。 这就是验证类型有用的地方,在JSON中它是
JsResult
,因此
InvalidFormat
应该是
JsError[DataFormat]

import play.api.libs.json._

sealed trait DataFormat
case object JsonFormat extends DataFormat
case object AnotherFormat extends DataFormat // at least 2 subtypes, otherwise no need to have a DataFormat trait but rather directly use JsonFormat

object DataFormat {
  implicit def writes: Writes[DataFormat] =
    implicitly[Writes[String]]. // Resolve default `Writes[String]`
      contramap[DataFormat] {
        case JsonFormat => "JSON"
        case AnotherFormat => "ANOTHER"
      }

  implicit def reads: Reads[DataFormat] =
    implicitly[Reads[String]]. // Resolve default `Reads[String]`
      collect[DataFormat](JsonValidationError("Invalid DataFormat")) {
        case "JSON" => JsonFormat
        case "ANOTHER" => AnotherFormat
      }
}
那么:

scala> Json.toJson[DataFormat](JsonFormat)
res0: play.api.libs.json.JsValue = "JSON"

scala> Json.toJson(AnotherFormat: DataFormat)
res2: play.api.libs.json.JsValue = "ANOTHER"

scala> JsString("JSON").validate[DataFormat]
res3: play.api.libs.json.JsResult[DataFormat] = JsSuccess(JsonFormat,)

scala> JsString("ANOTHER").validate[DataFormat]
res4: play.api.libs.json.JsResult[DataFormat] = JsSuccess(AnotherFormat,)

scala> JsString("FOO").validate[DataFormat]
res5: play.api.libs.json.JsResult[DataFormat] = JsError(List((,List(JsonValidationError(List(Invalid DataFormat),WrappedArray())))))

请在questionsobject DataFormat{隐式对象dataFormatObject扩展格式[DataFormat]{隐式定义读取(json:JsValue)=json匹配{case JsString(“json”)=>JsSuccess(json)case=>JsError(INVALID.toString)}隐式定义写入中正确格式化代码(dataFormat:dataFormat)=JsString(dataFormat.toString)}}隐式惰性val dataFormatWrites:Format[dataFormat]=DataFormat.dataFormatObject我这样写的这个也可以吗?是的,谢谢,但是我应该使用哪一个,您告诉的还是后面的?答案解释了,但是您应该使用enumeratum
import play.api.libs.json._

sealed trait DataFormat
case object JsonFormat extends DataFormat
case object AnotherFormat extends DataFormat // at least 2 subtypes, otherwise no need to have a DataFormat trait but rather directly use JsonFormat

object DataFormat {
  implicit def writes: Writes[DataFormat] =
    implicitly[Writes[String]]. // Resolve default `Writes[String]`
      contramap[DataFormat] {
        case JsonFormat => "JSON"
        case AnotherFormat => "ANOTHER"
      }

  implicit def reads: Reads[DataFormat] =
    implicitly[Reads[String]]. // Resolve default `Reads[String]`
      collect[DataFormat](JsonValidationError("Invalid DataFormat")) {
        case "JSON" => JsonFormat
        case "ANOTHER" => AnotherFormat
      }
}
scala> Json.toJson[DataFormat](JsonFormat)
res0: play.api.libs.json.JsValue = "JSON"

scala> Json.toJson(AnotherFormat: DataFormat)
res2: play.api.libs.json.JsValue = "ANOTHER"

scala> JsString("JSON").validate[DataFormat]
res3: play.api.libs.json.JsResult[DataFormat] = JsSuccess(JsonFormat,)

scala> JsString("ANOTHER").validate[DataFormat]
res4: play.api.libs.json.JsResult[DataFormat] = JsSuccess(AnotherFormat,)

scala> JsString("FOO").validate[DataFormat]
res5: play.api.libs.json.JsResult[DataFormat] = JsError(List((,List(JsonValidationError(List(Invalid DataFormat),WrappedArray())))))