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

时间:2018-09-20 16:45:35

标签: scala playframework optional-parameters joda-convert

我是Scala的新手,我的问题是有关使用play(2.5)获得Joda可选值的Json序列化 我的输入: 1。

first <- c("andrea","luis","mike","thomas")
last <- c("robinson", "trout", "rice","snell")
email <- c("andrea@gmail.com", "lt@gmail.com", "mr@gmail.com", "tom@gmail.com")



first <- c("mike","steven","mark","john", "martin")
last <- c("rice", "berry", "smalls","sale", "arnold")
email <- c("mr@gmail.com", "st@gmail.com", "ms@gmail.com", "js@gmail.com", "ma@gmail.com)
alz <- c(1,2,NA,3,4)
der <- c(0,2,3,NA,3)

all_emails <- data.frame(first,last,email)
no_contact_emails <- data.frame(first,last,email,alz,der)

df <- merge(no_contact_emails, all_emails, all = TRUE)

df <- df$email[!duplicated(df$email) & !duplicated(df$email, fromLast = TRUE)]
  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)
        }
    
  2. 测试对象:

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

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

  

重载的方法值适用于替代方法:     [B](f:B =>(String,Boolean,org.joda.time.LocalDateTime))(隐式fu:play.api.libs.functional.ContravariantFunctor [play.api.libs.json.Reads])播放。 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])播放。 api.libs.json.Reads [B]    不能应用于(((String,Boolean,Option [org.joda.time.LocalDateTime])=> com.dtos.User)         (JsPath \“活动”)。阅读[Boolean]和

    当$ ldt是lastLogin的子元素时,
  1. 不能使其适用于用户的输入Json结构:

    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 个答案:

答案 0 :(得分:0)

我认为您缺少的是串行器Format[LocalDateTime]

开箱即用地支持

Option

来自另一个Stackoverflow答案:

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]
}