Json4s定制的序列化器由于类型不匹配而无法工作。

问题描述 投票:0回答:1

我有一个包含密码字段的case类。为了安全起见,我需要在转换为Json时对其进行屏蔽,所以我为此创建了一个自定义的序列器,如下所示。

  import org.json4s.CustomSerializer
  import org.json4s._
  import scala.runtime.ScalaRunTime
  import org.json4s.jackson.JsonMethods._

  case class UserInfo(
                       userid: Long,
                       username: Option[String],
                       password: Option[String]
                     ) {
    override def toString: String = {
      val ui = this.copy(password = password.map(_ =>  "******"))
      ScalaRunTime._toString(ui)
    }
  }

  case object UserInfoSerializer extends CustomSerializer[UserInfo](format => ({
    case jsonObj: JObject =>
      implicit val formats = DefaultFormats
      jsonObj.extract[UserInfo]
  }, {
    case ui: UserInfo =>
      implicit val formats = DefaultFormats
      Extraction.decompose(ui.copy(password = ui.password.map(_ => "******")))
  }))

  implicit val formats = DefaultFormats + UserInfoSerializer

但是当我尝试转换 val ui = UserInfo(123, Some("anonymous"), Some("xxx")) 到一个Json字符串,通过 write(render(ui)),它总是失败的

scala> render(ui)
<console>:22: error: type mismatch;
 found   : UserInfo
 required: org.json4s.JValue
    (which expands to)  org.json4s.JsonAST.JValue
       render(ui)

我必须用它作为 render(Extraction.decompose(ui))或添加一个隐式转换,从 UserInfoJValue 作为 implicit def userInfo2JValue(ui: UserInfn) = Extraction.decompose(ui)

有什么办法可以让自定义序列器和默认序列器一样工作?

scala json4s
1个回答
0
投票

方法 render() 只是简单地渲染JSON AST,它不知道如何将你的类的实例转换为JValue。看看这个 图谱,它说明了用Json4s进行数据转换。长话短说,如果你想把你的类渲染成JSON字符串,你可以先把它转换为JValue,然后像你一样渲染。

 render(Extraction.decompose(ui))

或者你可以走捷径,使用 Serialization.write 在内部完成这两种操作。

 Serialization.write(ui)

不管是哪种情况,它都会使用你的自定义序列器,如果它已经添加了显式格式。

© www.soinside.com 2019 - 2024. All rights reserved.