2013-12-17 29 views
6

Merhaba Bir JSON gövde ayrıştırıcısıyla sorun yaşıyorum. Sorunum, bazı isteğe bağlı parametrelerle (Seçenek [T]) ve Seçenek [T] olarak yazılmasını istemediğim varsayılan bir değere sahip bir parametre içeren bir vaka sınıfım var. İşte Yürütme Scala JSON gövde ayrıştırıcısı varsayılan değer alanı

object MyController extends Controller{ 


    implicit val itemWrites = Json.writes[Item] 
    implicit val itemReads = Json.reads[Item] 
    implicit val itemFormats = Json.format[Item] 

    def add = DBAction(parse.json){ implicit rs => 

    val item = rs.request.body.validate[Item] 
} 

dosyamın sınıftır:

Ancak bir hata Burada

play.api.libs.JsError 
/count error path missing 

olsun ihmal varsayılan değerle alanına sahip bir JSON vücudu ayrıştırılırken benim denetleyicisi kodu

case class Item(id:Option[Int], name:String, description:Option[String], count:Int=0) 

Varsayılan değer alanıyla Seçenek [T] ile aynı davranışı yakalayabilir miyim?

Teşekkür kullanıyorum

:

  • Scala 2.10
  • Çal Çerçeve 2.2.1
  • Play-Slick eklentisi 0.5.0.8

cevap

4
+0

Merhaba, bir seçeneğim olmasını tercih ederim. Sağladığınız bağlantıya gelince. Kullanıcı mevcut çözümünün bazı dezavantajları olduğunu söylüyor ve kabul ettiğimi söylemeliyim. Bununla birlikte, daha iyi bir çözüm önerilmediyse, yaklaşımı – ufasoli

+0

etrafında göremediğim için sonlandırma yapacağım. En iyi çözüm, otomatik olarak withDefault oluşturmak için bir makro yazmayı gerektirecektir, bu durum oldukça zorlu bir iştir :( – Jean

+0

Evet bu Oldukça çok çaba ... – ufasoli

1

Bir geçici çözüm yazmak olacaktır: kesinlikle bir seçenek istemiyorsanız, buradan göz atabilirsiniz

case class Item(description:Option[String] = Some("String")) 

: Böyle bir Seçeneği ile varsayılan bir değer tanımlayabilirsiniz bir seçenek olarak sayımın varsayılan değerini alan ve yapıyı işleyen bir yöntem (Reads oluştururken açık bir ad vermemiz gerektiği gibi adlandıramaz):

object Item{ 
    def applyOpt(id:Option[Int], name:String, description:Option[String], count:Option[Int]): Item = count.map{c => 
    Item(id, name, description, c) 
    }.getOrElse{ 
    Item(id, name, description) 
    } 
} 
Eğer birkaç varsayılan alanlara sahip, özellikle eğer ideal değil Kesinlikle

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 


implicit val itemReads: Reads[Item] = (
    (__ \ "id").readNullable[Int] and 
    (__ \ "name").read[String] and 
    (__ \ "description").readNullable[String] and 
    (__ \ "count").readNullable[Int] 
)(Item.applyOpt _) 

ancak zorunluluğunu ortadan kaldırır hızlı bir geçici çözüm:

Sonra Birini applyOpt için [Uluslararası] geçecek olan varsayılan değeri readNullable kullanabilirsiniz Makro veya yansıma ile uğraşmak.

+0

evet ama aynı senaryoda bir çok vaka sınıfları var ama daha henüz henüz yazılmayan ve hataya eğilimli daha fazla alan var. % 100 kararlı ve güncellemeniz gerekiyor, Jackson'ın Java'da yaptığı gibi kutunun dışında çalışacağını umuyordum – ufasoli