为没有字段的Java Enum创建读/写

Kev*_*ith 6 enums json scala playframework

借助Play框架的JSON库,我怎么可以创建一个ReadsWrites对于没有领域一个Java枚举?

public enum EnumNoFields { RED, WHITE, BLUE }

implicit val EnumNoFieldsReads: Reads[EnumNoFields] = ?
implicit val EnumNoFieldsWrites: Writes[EnumNoFields] = ?
Run Code Online (Sandbox Code Playgroud)

Kev*_*ith 6

我只是使用了Enum#name.

  implicit val EnumNoFieldsReads: Reads[EnumNoFields] =
    (JsPath \ "displayValue").read[String].map{x: String => EnumNoFields.valueOf(x)}

  implicit val EnumNoFieldsWrites: Writes[EnumNoFields] =
    (JsPath \ "displayValue").write[String].contramap{x:EnumNoFields => x.name}
Run Code Online (Sandbox Code Playgroud)

  • 如果我今天要回答这个问题,我建议年轻的自己看看 https://github.com/lloydmeta/enumeratum! (2认同)

Mar*_*ier 6

通用解决方案如下所示:

def javaEnumFormat[E <: Enum[E] : ClassTag] = new Format[E] {
  override def reads(json: JsValue): JsResult[E] = json.validate[String] match {
    case JsSuccess(value, _) => try {
      val clazz = implicitly[ClassTag[E]].runtimeClass.asInstanceOf[Class[E]]
      JsSuccess(Enum.valueOf(clazz, value))
    } catch {
      case _: IllegalArgumentException => JsError("enumeration.unknown.value")
    }
    case JsError(_) => JsError("enumeration.expected.string")
  }

  override def writes(o: E): JsValue = JsString(o.toString)
}
Run Code Online (Sandbox Code Playgroud)

您可以这样使用:

implicit val enumNoFieldsFormat = javaEnumFormat[EnumNoFields]