2013-12-17 24 views
6

Hallo Ich habe Probleme mit einem JSON Body Parser. Mein Problem ist folgendes Ich habe eine Fallklasse mit einigen optionalen Parametern (Option [T]) und einen Parameter mit einem Standardwert, der nicht als Option [T] eingegeben werden soll.Spielen Scala JSON Body Parser Standardwert Feld

jedoch, wenn ein JSON Körper Parsen das Feld mit dem Standardwert mit weggelassen ich einen Fehler ist

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

Hier mein Controller-Code:

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

Hier meinem Fall-Klasse ist:

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

Gibt es eine Chance, das gleiche Verhalten wie Option [T] mit dem Standardwert Feld zu erreichen?

Dank

Ich verwende:

  • Scala 2.10
  • Play-Framework-2.2.1
  • Wiedergabe-Slick Plugin 0.5.0.8

Antwort

4

Fast. Sie können einen Standardwert mit einer Option wie folgt definieren:

Defaults for missing properties in play 2 JSON formats

+0

Hallo, danke, ich hätte lieber keine Option. Wie für den Link, den Sie angegeben haben. Der Benutzer gibt an, dass seine derzeitige Lösung einige Nachteile hat, und ich muss sagen, dass ich dem zustimme. Wenn jedoch keine bessere Lösung vorgeschlagen wird, werde ich seinen Ansatz verwenden, da ich keinen Weg sehe. – ufasoli

+0

Die beste Lösung würde beinhalten, ein Makro zu schreiben, um automatisch den withDefault zu erstellen, dies ist jedoch ziemlich das Unterfangen :( – Jean

+0

Ja das ist ziemlich viel Mühe ... – ufasoli

1

Eine Abhilfe wäre zu schreiben:

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

Wenn Sie auf jeden Fall, keine Option möchten Sie einen Blick hier haben eine Methode apply, die den Standardwert count als Option einnimmt und die Konstruktion übernimmt (kann sie nicht benennen, da wir einen unzweideutigen Namen beim Erstellen unserer Lesevorgänge benötigen):

Dann könnten Sie readNullable für den Standardwert verwenden, die eine Option [Int] zu applyOpt passieren:

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

sicher nicht ideal, vor allem, wenn Sie mehrere Standardfelder haben, aber eine schnelle Abhilfe, die mit vermeidet beschäftigen sich mit Makros oder Reflektion.

+0

ja, aber ich hatte gehofft zu vermeiden, den Reader mit allen Feldern zu schreiben, als aa viele Fall Klassen mit dem gleichen Szenario aber mehr Felder, die mühsam zu schreiben und fehleranfällig ist, wenn das Modell noch nicht ist 100% stabil und du musst es aktualisieren, ich hatte gehofft, es würde einfach so funktionieren wie Jackson in Java – ufasoli