如何在 Play 中使用 Joda DateTime Json
How to use Joda DateTime with Play Json
我正在开发一个 Play 应用程序,我正在尝试在我的案例中使用 Joda DateTime 对象 class。
package model
import org.joda.time.DateTime
import play.api.libs.json._
case class User(name: String, created: DateTime)
object User {
implicit val yourJodaDateReads = Reads.jodaDateReads("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
implicit val yourJodaDateWrites = Writes.jodaDateWrites("yyyy-MM-dd'T'HH:mm:ss.SSSZ'")
implicit val userFormat = Json.format[User]
def main(args: Array[String]) {
val value = Json.parse("{ \"name\" : \"hello\" , \"created\" : \"2015-07-16T20:32:04.046+02:00\" }")
println(Json.toJson(new User("user", new DateTime())))
println(Json.fromJson(value))
}
}
基于此 solution,我收到此错误:
Error:(18, -1) Play 2 Compiler:
/activator-1.3.2/notifier-app/app/model/Test.scala:18: ambiguous implicit values:
both value yourJodaDateReads in object User of type => play.api.libs.json.Reads[org.joda.time.DateTime]
and value userFormat in object User of type => play.api.libs.json.OFormat[model.User]
我正在使用 Activator 1.3.2 和 Play 2.3.8。
你能给我点建议吗?
提前致谢。
更新
我了解 play.api.libs.json.Reads
中的隐含值存在冲突
implicit val DefaultJodaDateReads = jodaDateReads("yyyy-MM-dd")
我该如何解决这个问题?
期待更好的选择,这里是我的解决方法:
val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
val jodaDateReads = Reads[DateTime](js =>
js.validate[String].map[DateTime](dtString =>
DateTime.parse(dtString, DateTimeFormat.forPattern(dateFormat))
)
)
val jodaDateWrites: Writes[DateTime] = new Writes[DateTime] {
def writes(d: DateTime): JsValue = JsString(d.toString())
}
val userReads: Reads[User] = (
(JsPath \ "name").read[String] and
(JsPath \ "created").read[DateTime](jodaDateReads)
)(User.apply _)
val userWrites: Writes[User] = (
(JsPath \ "name").write[String] and
(JsPath \ "created").write[DateTime](jodaDateWrites)
)(unlift(User.unapply))
implicit val userFormat: Format[User] = Format(userReads, userWrites)
我认为您应该在 Json.toJson
和 Json.fromJson
函数中设置 User
类型。而不是
println(Json.toJson(new User("user", new DateTime())))
println(Json.fromJson(value))
尝试:
println(Json.toJson[User](new User("user", new DateTime())))
println(Json.fromJson[User](value))
当您显式设置类型时,框架会知道reads/writes要使用什么。
更新:
不必为 Json.toJson
函数设置类型,因为您将 User
对象作为函数参数传递,并且框架在运行时确定类型。
但是对于Json.fromJson[User]
你必须设置类型,否则框架不知道你要读取的对象的类型。
试试这些:
implicit val dateWrites = jodaDateWrites("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
implicit val dateReads = jodaDateReads("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
我知道这个问题已经回答了一段时间,但我找到了一个更简洁的答案
val pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
implicit val dateFormat = Format[DateTime](Reads.jodaDateReads(pattern), Writes.jodaDateWrites(pattern))
implicit val userFormat = Json.format[User]
在 play 2.6 中,serialize/deserialize joda DateTime json 的规范方法是通过更新 build.sbt
使用 play-json-joda library. Import the library。然后像这样创建 json reader 和 json 作者:
import play.api.libs.json.JodaWrites
implicit val dateTimeWriter: Writes[DateTime] = JodaWrites.jodaDateWrites("dd/MM/yyyy HH:mm:ss")
import play.api.libs.json.JodaReads
implicit val dateTimeJsReader = JodaReads.jodaDateReads("yyyyMMddHHmmss")
我正在开发一个 Play 应用程序,我正在尝试在我的案例中使用 Joda DateTime 对象 class。
package model
import org.joda.time.DateTime
import play.api.libs.json._
case class User(name: String, created: DateTime)
object User {
implicit val yourJodaDateReads = Reads.jodaDateReads("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
implicit val yourJodaDateWrites = Writes.jodaDateWrites("yyyy-MM-dd'T'HH:mm:ss.SSSZ'")
implicit val userFormat = Json.format[User]
def main(args: Array[String]) {
val value = Json.parse("{ \"name\" : \"hello\" , \"created\" : \"2015-07-16T20:32:04.046+02:00\" }")
println(Json.toJson(new User("user", new DateTime())))
println(Json.fromJson(value))
}
}
基于此 solution,我收到此错误:
Error:(18, -1) Play 2 Compiler:
/activator-1.3.2/notifier-app/app/model/Test.scala:18: ambiguous implicit values:
both value yourJodaDateReads in object User of type => play.api.libs.json.Reads[org.joda.time.DateTime]
and value userFormat in object User of type => play.api.libs.json.OFormat[model.User]
我正在使用 Activator 1.3.2 和 Play 2.3.8。
你能给我点建议吗?
提前致谢。
更新
我了解 play.api.libs.json.Reads
中的隐含值存在冲突implicit val DefaultJodaDateReads = jodaDateReads("yyyy-MM-dd")
我该如何解决这个问题?
期待更好的选择,这里是我的解决方法:
val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
val jodaDateReads = Reads[DateTime](js =>
js.validate[String].map[DateTime](dtString =>
DateTime.parse(dtString, DateTimeFormat.forPattern(dateFormat))
)
)
val jodaDateWrites: Writes[DateTime] = new Writes[DateTime] {
def writes(d: DateTime): JsValue = JsString(d.toString())
}
val userReads: Reads[User] = (
(JsPath \ "name").read[String] and
(JsPath \ "created").read[DateTime](jodaDateReads)
)(User.apply _)
val userWrites: Writes[User] = (
(JsPath \ "name").write[String] and
(JsPath \ "created").write[DateTime](jodaDateWrites)
)(unlift(User.unapply))
implicit val userFormat: Format[User] = Format(userReads, userWrites)
我认为您应该在 Json.toJson
和 Json.fromJson
函数中设置 User
类型。而不是
println(Json.toJson(new User("user", new DateTime())))
println(Json.fromJson(value))
尝试:
println(Json.toJson[User](new User("user", new DateTime())))
println(Json.fromJson[User](value))
当您显式设置类型时,框架会知道reads/writes要使用什么。
更新:
不必为 Json.toJson
函数设置类型,因为您将 User
对象作为函数参数传递,并且框架在运行时确定类型。
但是对于Json.fromJson[User]
你必须设置类型,否则框架不知道你要读取的对象的类型。
试试这些:
implicit val dateWrites = jodaDateWrites("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
implicit val dateReads = jodaDateReads("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
我知道这个问题已经回答了一段时间,但我找到了一个更简洁的答案
val pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
implicit val dateFormat = Format[DateTime](Reads.jodaDateReads(pattern), Writes.jodaDateWrites(pattern))
implicit val userFormat = Json.format[User]
在 play 2.6 中,serialize/deserialize joda DateTime json 的规范方法是通过更新 build.sbt
使用 play-json-joda library. Import the library。然后像这样创建 json reader 和 json 作者:
import play.api.libs.json.JodaWrites
implicit val dateTimeWriter: Writes[DateTime] = JodaWrites.jodaDateWrites("dd/MM/yyyy HH:mm:ss")
import play.api.libs.json.JodaReads
implicit val dateTimeJsReader = JodaReads.jodaDateReads("yyyyMMddHHmmss")