【问题标题】:Scala json4s sealed trait as enumsScala json4s 密封特征作为枚举
【发布时间】:2015-09-17 01:54:21
【问题描述】:

我们的状态定义为:

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

有没有办法用预定义的json4s fomratters 对这种结构进行(反)序列化?

我们尝试使用默认格式化程序,例如:

implicit val formats = new org.json4s.DefaultFormats

它没有工作。接下来我们尝试使用 json4s 提供的 ext 并支持 Enum:

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

它没有再次工作。我们必须将sealed trait 的结构完全更改为实际的Enumerations。 case classes 有什么办法吗?

【问题讨论】:

    标签: scala enums traits json4s sealed


    【解决方案1】:

    这是一个完整的工作示例,我稍微更改了您的类以使示例更简单,这样您可以以不同的方式使用“名称”,您实际上可以省略“定义名称”,但在这种情况下,您将需要稍微改变一下序列化器。第二个序列化器就在下面。

    
    
        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")
        }
    
    

    这是第二个序列化器,通过使用第二个序列化器,您无需在“枚举”中定义额外的代码

    
    
        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",
      "someInt":42,
      "statuses":["StatusA","StatusB","StatusC"]
    }

    Rich object toString: SimpleRichObject(Here is a another String,1234,List(StatusA, StatusB))

    【讨论】:

      猜你喜欢
      • 2012-11-21
      • 1970-01-01
      • 2019-09-07
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-08
      • 2017-09-08
      相关资源
      最近更新 更多