加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala json4s密封了特征作为枚举

发布时间:2020-12-16 18:28:38 所属栏目:安全 来源:网络整理
导读:我们的状态定义为: sealed trait Statuscase object Status { case object StatusA extends Status case object StatusB extends Status case object StatusC extends Status} 我们的状态如下: val status = Status.StatusA 有没有办法(de)使用预定义的jso
我们的状态定义为:

sealed trait Status
case object Status {
  case object StatusA extends Status
  case object StatusB extends Status
  case object StatusC extends Status
}

我们的状态如下:

val status = Status.StatusA

有没有办法(de)使用预定义的json4s fomratters序列化这种结构?

我们尝试使用defult formatter:

implicit val formats = new org.json4s.DefaultFormats

它不起作用.接下来我们尝试使用json4s提供的ext和Enum支持:

implicit val formats = org.json4s.DefaultFormats + new org.json4s.ext.EnumSerializer(Status)

它不再起作用了.我们必须将密封特性的结构完全改为实际的枚举.有没有办法用案例类做?

解决方法

这是一个完整的工作示例,我更改了一些类以使示例更简单,这样您可以使用“名称”以不同的方式实际省略“def name”,但在这种情况下,您将需要更改串行器有点.第二个Serializer就在??下面.

sealed trait Status {
      def name: String
    }

    case object Status {
      def apply(name: String): Status = name match {
        case StatusA.name => StatusA
        case StatusB.name => StatusB
        case StatusC.name => StatusC
        case _ => throw new UnsupportedOperationException("Unknown value")
      }
    }

    case object StatusA extends Status {
      override val name = "StatusA"
    }

    case object StatusB extends Status {
      override val name = "StatusB"
    }

    case object StatusC extends Status {
      override val name = "StatusC"
    }

    class StatusSerializer extends CustomSerializer[Status](formats =>
      ( {
        case JString(s) => Status(s)
        case JNull => throw new UnsupportedOperationException("No status specified")
      },{
        case status: Status => JString(status.name)
      })
    )

    case class SimpleRichObject(someString: String,someInt: Int,statuses: List[Status])

    object Test extends App {
      implicit val formats = DefaultFormats + new StatusSerializer
      val obj = SimpleRichObject("Answer to life the universe and everything",42,List(StatusA,StatusB,StatusC))

      def toCompactJsonString(any: Any) = {
        JsonMethods.compact(JsonMethods.render(Extraction.decompose(any)))
      }

      def toPrettyJsonString(any: Any) = {
        JsonMethods.pretty(JsonMethods.render(Extraction.decompose(any)))
      }

      /** To Json */
      println(s"Compact json:n${toCompactJsonString(obj)}")
      println(s"Pretty json:n${toPrettyJsonString(obj)}")

      /** From Json */
      val json =
        """{
          |  "someString":"Here is a another String",|  "someInt":1234,|  "statuses":["StatusA","StatusB"]
          |}""".stripMargin

      val richObj = JsonMethods.parse(json).extract[SimpleRichObject]
      println(s"Rich object toString: $richObj")
    }

这是第二个Serializer,使用第二个,您不需要在“Enums”中定义额外的代码

class SecondStatusSerializer extends CustomSerializer[Status](formats =>
      ( {
        case JString(s) => s match {
          case "StatusA" => StatusA
          case "StatusB" => StatusB
          case "StatusC" => StatusC
        }
        case JNull => throw new UnsupportedOperationException("No status specified")
      },{
        case status: Status => status match {
          case StatusA => JString("StatusA")
          case StatusB => JString("StatusB")
          case StatusC => JString("StatusC")
        }
      })
    )

在这里,这个看起来如何运行,紧凑json:

{"someString":"Answer to life the universe and everything","someInt":42,"statuses":["StatusA","StatusB","StatusC"]}

漂亮的json:

{
  "someString":"Answer to life the universe and everything","StatusC"]
}

Rich对象toString:SimpleRichObject(这是另一个String,1234,StatusB))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读