Scala,使用 play 2.5 将 joda.LocalDateTime 转换为 json

Posted

技术标签:

【中文标题】Scala,使用 play 2.5 将 joda.LocalDateTime 转换为 json【英文标题】:Scala, convert joda.LocalDateTime to json with play 2.5 【发布时间】:2019-02-25 00:54:32 【问题描述】:

我是 Scala 新手,我的问题是关于使用 play (2.5) 对 Joda 的可选值进行 Json 序列化 我的输入: 1.

import org.joda.time.LocalDateTime
     case class User(
                     name: String, 
                     lastLogin: Option[LocalDateTime])
    object User 
      implicit val serializers = JsonSerializers
      implicit val UserFormat: Format[User] = Format(serializers.UserReads, serializers.UserWrites)
    

    序列化器

    import com.dtos.User
    import org.joda.time.LocalDateTime
    import org.joda.time.format.DateTimeFormat
    import play.api.libs.json._
    import play.api.libs.functional.syntax._
    object JsonSerializers 
      val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
    
      implicit val UserReads: Reads[User] = (
        (JsPath \ "name").read [String] and
          (JsPath \ "active").read [Boolean] and
          (JsPath \\ "$ldt").read[LocalDateTime]
        )(User.apply _)
    
      implicit val UserWrites: Writes[User] = (
        (JsPath \ "name").write [String] and
          (JsPath \ "active").write [Boolean] and
          (JsPath \ "lastLogin" \ "$ldt") .write [LocalDateTime]
        )(unlift (User.unapply))
    
    

    测试对象:

    object MainTest extends App     
      val value: JsValue = Json.parse(" \"name\" : \"hello\" , \"lastLogin\" : \"$ldt\":\"2018-09-09T11:06:27.655\" ")
      println("First Output:")
      println(Json.toJson(new MyUser("user", LocalDateTime.now)))
      println("Second Output:")
      println(Json.fromJson(value))    
    
    

问题: 1. UserReads/UserWrites 期间如何管理 Option 值? 我收到以下错误:

重载的方法值适用于替代方案: [B](f: B => (String, Boolean, org.joda.time.LocalDateTime))(隐式 fu: play.api.libs.functional.ContravariantFunctor[play.api.libs.json.Reads])play. api.libs.json.Reads[B] [B](f: (String, Boolean, org.joda.time.LocalDateTime) => B)(隐式 fu: play.api.libs.functional.Functor[play.api.libs.json.Reads])play. api.libs.json.Reads[B] 不能应用于 ((String, Boolean, Option[org.joda.time.LocalDateTime]) => com.dtos.User) (JsPath\"active").read [Boolean] 和

    当 $ldt 是 lastLogin 的子元素时,无法使其对用户的输入 Json 结构起作用:

     val value: JsValue = Json.parse(" \"name\" : \"hello\" , \"lastLogin\" : \"$ldt\":\"2018-09-09T11:06:27.655\" ")
    
    (means User is defined by:
    "name\":\"myName\",
    \"active\":true,
    \"lastLogin\":\"$ldt\":\"2018-09-09T11:06:27.655\"
    
    )
    

【问题讨论】:

看看readOptwriteOpt @cchantep,这就是我所缺少的!!就我而言,它是关于 readNullable 和 writeNullable - 就像魔法一样。 【参考方案1】:

我认为您缺少的是序列化程序Format[LocalDateTime]

Option 支持开箱即用。

取自另一个 *** 答案:

import org.joda.time.LocalDateTime
import org.joda.time.format.ISODateTimeFormat

implicit val readsJodaLocalDateTime = Reads[LocalDateTime](js =>
  js.validate[String].map[LocalDateTime](dtString =>
    LocalDateTime.parse(dtString, ISODateTimeFormat.basicDateTime())
  )
)

在这里查看完整答案:custom-jodatime-serializer-using-play-frameworks-json-library

顺便说一句,你可以像这样添加一个序列化器:

object User 
  implicit val jsonFormat: Format[User] = Json.format[User]

【讨论】:

以上是关于Scala,使用 play 2.5 将 joda.LocalDateTime 转换为 json的主要内容,如果未能解决你的问题,请参考以下文章

Scala Play 2.5 与 Slick 3 和 Spec2

使用 Play Framework JSON 库的自定义 Joda 时间序列化器?

玩 2.5 剪影 4 - 带有 guice 的 DI

玩法 2.5:模板中的依赖注入

如何将参数注入Scala中的类/特征方法

如何将 IntelliJ 与 Play Framework 和 Scala 一起使用