使用json4s序列化和反序列化Scala枚举或case对象

9
假设我有一个枚举类型或者封闭的 Case 对象组,如下所示:
  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)
  }
}
1个回答

24
我们使用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)
    }
  )
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接