2015-07-16 16 views
9

Sto sviluppando un'applicazione Play e sto cercando di utilizzare un oggetto DateTime Joda nella mia classe case.Come utilizzare Joda DateTime con Play Json

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

Sulla base di questo solution, sto ottenendo questo errore:

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] 

sto usando Activator 1.3.2 and Play 2.3.8.

Potresti per favore avvisarmi?

Grazie in anticipo.

aggiornamento

Capisco che ci sia un conflitto con il valore implicito nel play.api.libs.json.Reads

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

Come posso risolvere questo problema?

+0

possibile duplicato (http: // StackOverflow.it/questions/18255504/custom-jodatime-serializer-using-play-frameworks-json-library) –

+0

Leggere il mio post anziché rispondere a una risposta errata. Ho citato questo link perché il mio codice è basato su questa discussione .. – Guillaume

risposta

17

attesa di un'alternativa migliore, qui la mia soluzione:

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

Finalmente ho capito Play Format. – Fabio

1

Penso che si dovrebbe impostare il tipo User in Json.toJson e Json.fromJson funzioni. Invece di

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

prova:

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

Quando si imposta il tipo in modo esplicito quadro sapranno cosa letture/scritture da usare.

Aggiornamento: Non è necessariamente impostare tipo per Json.toJson funzione perché si passa User oggetto come argomento di funzione e quadro determina il tipo di runtime. Ma per Json.fromJson[User] devi impostare il tipo, altrimenti il ​​framework non conosce il tipo dell'oggetto che vuoi leggere.

3

So che questa domanda è stato risposto per un po ', ma ho trovato una risposta più concisa

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 gioca 2.6, il modo canonico per serializzare/deserializzare joda DateTime json sta usando la libreria play-json-joda. Import the library aggiornando il tuo build.sbt. Quindi creare lettore di JSON e JSON scrittori come questo: [? Personalizzato JodaTime serializzatore utilizzando la libreria Play quadro 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") 
+2

Il gioco 2.6 ha così tante belle funzionalità, continuo a trovare piccole variazioni di qualità della vita come questa – ObjectiveTruth

+0

Io voto perché questa sia la nuova risposta accettata –

Problemi correlati