【问题标题】:Serialize and Deserialize scala enumerations or case objects using json4s使用 json4s 序列化和反序列化 scala 枚举或案例对象
【发布时间】:2014-08-18 00:29:20
【问题描述】:

假设我有一个枚举或密封的案例对象组,如下所示:

  sealed abstract class Status
  case object Complete extends Status
  case object Failed extends Status
  case object Pending extends Status
  case object Unknown extends Status

  object Status extends Enumeration {
    val Complete, Failed, Pending, Unknown = Value
  }

为这些创建 json 格式的最简单方法是什么,以便我可以非常轻松地(以编程方式)生成 json 格式以用于自定义 JsonFormat 工厂方法,如下所示,适用于所有普通案例类,字符串、集合等,但为上述两种枚举类型产生{}{"name": null}?:

import org.json4s.DefaultFormats
import org.json4s.jackson.JsonMethods.parse
import org.json4s.jackson.Serialization
import org.json4s.jvalue2extractable
import org.json4s.string2JsonInput

trait JsonFormat[T] {
  def read(json: String): T
  def write(t: T): String
}

object JsonFormat {

  implicit lazy val formats = DefaultFormats

  def create[T <: AnyRef: Manifest](): JsonFormat[T] = new JsonFormat[T] {
    def read(json: String): T = parse(json).extract[T]
    def write(t: T): String = Serialization.write(t)
  }
}

【问题讨论】:

    标签: scala json4s


    【解决方案1】:

    我们使用org.json4s.ext.EnumNameSerializer 来序列化枚举:

    import org.json4s._
    import org.json4s.ext.EnumNameSerializer
    
    class DoesSomething {
      implicit lazy val formats = DefaultFormats + new EnumNameSerializer(Status)
    
      ...stuff requiring serialization or deserialization...
    }
    

    在实践中,我们有 mixin trait,它添加了隐式格式并定义了我们所有的自定义序列化器/反序列化器:

    trait OurFormaters extends Json4sJacksonSupport {
      implicit lazy val json4sJacksonFormats:Formats = DefaultFormats +
        UuidSerializer +       
        new EnumNameSerializer(Status) +
        ...
    }
    
    object UuidSerializer extends CustomSerializer[UUID](format =>
      (
        {
          case JString(s) => UUID.fromString(s)
          case JNull => null
        },
        {
          case x: UUID => JString(x.toString)
        }
      )
    )
    

    【讨论】: