5

Fonksiyonel sözdizimini kullanarak özel bir json serializer yazmaya çalışıyorum ve bu sorunu çözmek için doğru yolu bulamıyorum. Kullanmakta olan kullanıcı arabirimi için belirli bir biçimde yazmak istediğim birkaç joda DateTime nesnesi var. Nerede yanlış gittiğimi kimse gösterebilir mi?scala play 2.1.1 json işlevsel sözdizimi farklı bir formata eşleme verileri

Şu an için uğraştığım örnek sınıf, özel bir şey yok.

case class Banner(
    id: Int = 0, 
    ownerId: Int = 0, 
    licenseeId: Option[Int] = None, 
    statusColor: Option[String] = None, 
    content: Option[String] = None, 
    displayStart: DateTime = new DateTime(), 
    displayEnd: DateTime = new DateTime(), 
    created: DateTime = new DateTime(), 
    updated: DateTime = new DateTime() 
) 

Bunlar benim serializer nesnesi için benim ithalatım.

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 
import org.joda.time.DateTime 
import org.joda.time.format.DateTimeFormat 

Öncelikle, söylediğin bütün istediğim eğer makro genişletici iyi çalışıyor bu yüzden DateTime örtülü uzun gayet dönüşür joda. Ben gerekenler

object MySerializers { 
    implicit val writesBanner = Json.writes[Banner] 
} 

belirli dize biçimi yerine uzun değere displayStart ve displayEnd nesneleri dönüştürmek içindir. Yapmaya çalıştığım buydu.

object MySerializers { 
    val userDateFormatter = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm a") 

    implicit val writesBanner = (
    (__ \ "id").write[Int] and 
    (__ \ "ownerId").write[Int] and 
    (__ \ "licenseeId").write[Int] and 
    (__ \ "statusColor").writeNullable[String] and 
    (__ \ "content").writeNullable[String] and 
    (__ \ "displayStart").write[DateTime].inmap[String](dt => userDateFormatter.print(dt)) and 
    (__ \ "displayEnd").write[DateTime].inmap[String](dt => userDateFormatter.print(dt)) and 
    (__ \ "created").write[DateTime] and 
    (__ \ "updated").write[DateTime] 
)(unlift(Banner.unapply)) 
} 

Ama derleyici bu konuda mutlu değil, bu yüzden inmap fonksiyonunu kullanmak için doğru şekilde anlamak için görünmüyor.

could not find implicit value for parameter fu: 
play.api.libs.functional.InvariantFunctor[play.api.libs.json.OWrites] 
[error]  (__ \ "displayStart").write[DateTime].inmap[String](dt =>  
userDateFormatter.print(dt)) and 
[error]        ^

Herhangi bir öneri çok takdir edilmektedir.

cevap

5

Bunu çözmeyi başardım, yanlış tipte harita operasyonları kullanıyordum ve geriye doğru çalıştığım tipler vardı. İşte çok güzel işlevsel sözdiziminde okuma/yazma uygulamaları var.

implicit val writesBanner = (
    (__ \ "id").write[Int] and 
    (__ \ "ownerId").write[Int] and 
    (__ \ "licenseeId").writeNullable[Int] and 
    (__ \ "statusColor").writeNullable[String] and 
    (__ \ "content").writeNullable[String] and 
    (__ \ "displayStart").write[String].contramap[DateTime](dt => userDateFormatter.print(dt)) and 
    (__ \ "displayEnd").write[String].contramap[DateTime](dt => userDateFormatter.print(dt)) and 
    (__ \ "created").write[DateTime] and 
    (__ \ "updated").write[DateTime] 
)(unlift(Banner.unapply)) 

implicit val readsBanner = (
    (__ \ "id").read[Int] and 
    (__ \ "ownerId").read[Int] and 
    (__ \ "licenseeId").readNullable[Int] and 
    (__ \ "statusColor").readNullable[String] and 
    (__ \ "content").readNullable[String] and 
    (__ \ "displayStart").read[String].fmap[DateTime](dt => DateTime.parse(dt, userDateFormatter)) and 
    (__ \ "displayEnd").read[String].fmap[DateTime](dt => DateTime.parse(dt, userDateFormatter)) and 
    (__ \ "created").read[DateTime] and 
    (__ \ "updated").read[DateTime] 
)(Banner) 
+0

neden 'yerine .format' kullanmak yok' .read' + '.write'? –

2

Kesinlikle bu konuda uzman değilim ama inmap kullanmak yolu contramap/fmap nasıl kullandığınıza bir kombinasyonudur eminim. olduğu

:

implicit val formatBanner = (
<truncated> 
    (__ \ "displayStart").format[String].inmap(DateTime.parse(_, userDateFormatter), userDateFormatter.print(_)) and 
<truncated> 
)(Banner.apply, unlift(Banner.unapply))