2015-07-16 6 views
9

Ich entwickle eine Play-Anwendung, und ich versuche, ein Joda DateTime-Objekt in meiner Fallklasse zu verwenden.Wie man Joda DateTime mit Play Json verwendet

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

Basierend auf dieser solution, erhalte ich diese Fehlermeldung:

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] 

Ich bin mit Activator 1.3.2 und 2.3.8 Wiedergabe.

Könnten Sie mich bitte beraten?

Vielen Dank im Voraus.

Update

Ich verstehe ein Konflikt mit dem impliziten Wert gibt es in play.api.libs.json.Reads

implicit val DefaultJodaDateReads = jodaDateReads("yyyy-MM-dd") 

Wie kann ich dieses Problem beheben?

+0

mögliche Duplikate von [Custom JodaTime Serializer mit JSON-Bibliothek von Play Framework?] (Http: // Stackoverflow.com/questions/18255504/custom-jodatime-serializer-using-play-frameworks-json-library) –

+0

Bitte lesen Sie meinen Beitrag, anstatt eine schlechte Antwort zu beantworten. Ich habe diesen Link zitiert, weil mein Code auf diesem Thread basiert. – Guillaume

Antwort

17

Erwartet eine bessere Alternative, hier meine Abhilfe:

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) 
+1

Endlich verstand ich Play Format. – Fabio

1

Ich denke, Sie sollten die User Art in Json.toJson und Json.fromJson Funktionen einstellen. Statt

println(Json.toJson(new User("user", new DateTime()))) 
println(Json.fromJson(value)) 

Versuch:

println(Json.toJson[User](new User("user", new DateTime()))) 
println(Json.fromJson[User](value)) 

Wenn Sie den Typ explizit Rahmen gesetzt wird wissen, was liest/schreibt zu verwenden.

Update: Es ist nicht unbedingt Typ für Json.toJson Funktion zu setzen, weil Sie User Objekt als Funktion Argument übergeben und Rahmen bestimmt die Art in der Laufzeit. Aber für Json.fromJson[User] müssen Sie den Typ festlegen, andernfalls kennt das Framework den Typ des Objekts nicht, das Sie lesen möchten.

3

Ich weiß, diese Frage für eine Weile beantwortet wurde, aber ich fand eine knappe Antwort

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

In Spielen Sie 2.6, den kanonischen Weg, joda DateTime zu serialisieren/deserialisieren Json ist mit der play-json-joda Bibliothek. Import the library durch Aktualisierung Ihrer build.sbt. Erstellen Sie dann JSON-Reader und JSon-Writer wie folgt:

+2

Play 2.6 hat so viele nette Features, ich finde kleine Veränderungen des Lebens, wie diese – ObjectiveTruth

+0

Ich stimme, dass dies die neue akzeptierte Antwort sein wird –

Verwandte Themen