2014-06-02 3 views
1

У меня есть:Play JSON Комбинаторы OrElse не работает на двойной поле

case class Product( 
    id: Option[Int], 
    name: String, 
    measure: Int, 
    qty: Double = 0 
) 

и неявное JSON Reads в контроллере:

implicit val productReads: Reads[Product] = (
    (JsPath \ "id").readNullable[Int] and 
    (JsPath \ "name").read[String] and 
    (JsPath \ "measure").read[Int] and 
    (JsPath \ "qty").read[Double].orElse(Reads.pure(0)) 
)(Product) 

и здесь createProduct действие:

def createProduct = DBAction(parse.json) { implicit rs => 
    rs.request.body.validate[Product].map { product => 
    Logger.info(s"createProduct product:$product") 
    //... 
    Ok(toJson(product)) 
    }.recoverTotal { errors => 
    BadRequest(errors.toString) 
    } 
} 

Таким образом, поле qty имеет значение по умолчанию 0. Если клиент не отправил это поле, анализатор должен получить значение по умолчанию, но когда я хочу попробовать создать продукт, появляется следующее сообщение об ошибке:

JsError(List((/qty,List(ValidationError(error.path.missing,WrappedArray())))) 

Вслед за JSON клиент послал:

{ 
    "measure": 1, 
    "name": "meat" 
} 

Почему? Кто-нибудь знает, где моя ошибка?

ответ

4

Я попытался запустить это в REPL, используя play console, и все работает отлично. orElse отлично работает с Double. Приклеивание в следующем:

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

case class Product( 
    id: Option[Int], 
    name: String, 
    measure: Int, 
    qty: Double = 0 
) 

implicit val productReads: Reads[Product] = (
    (JsPath \ "id").readNullable[Int] and 
    (JsPath \ "name").read[String] and 
    (JsPath \ "measure").read[Int] and 
    (JsPath \ "qty").read[Double].orElse(Reads.pure(0)) 
)(Product) 

Json.parse("""{"measure": 1, "name": "meat"}""").validate[Product] 

возвращается:

play.api.libs.json.JsResult[Product] = JsSuccess(Product(None,meat,1,0.0),) 

Кажется, что есть еще одна Reads[Product] определена в объеме def createProduct вместо того, вы предоставили, в противном случае оно должно работать. Возможно, макрос JSON?

+0

ooh, вы абсолютно правы @ LimbSoup, я проверил поворот, я остаюсь старым "неявным val productFormat = Json.format [Product]", большое спасибо @LimbSoup !!! –

0

AFAIK библиотека Play JSON не поддерживает значения класса case по умолчанию. См. Также this question.