2013-12-17 19 views
6

Xin chào, tôi đang gặp sự cố với trình phân tích cú pháp cơ thể JSON. Vấn đề của tôi là sau đây tôi có một trường hợp lớp với một số tham số tùy chọn (Option [T]) và một tham số với một giá trị mặc định mà tôi không muốn được gõ là Option [T].Chơi trường giá trị mặc định của trình phân tích cú pháp nội dung JSON Scala

Tuy nhiên khi phân tích một cơ thể JSON có đồng ruộng với giá trị mặc định bỏ qua tôi nhận được một lỗi

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

Đây là mã điều khiển của tôi:

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

Đây là lớp trường hợp của tôi:

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

Bất kỳ cơ hội nào tôi có thể đạt được hành vi tương tự như Tùy chọn [T] với trường giá trị mặc định?

Cảm ơn

Tôi đang sử dụng:

  • Scala 2.10
  • Chơi Khung 2.2.1
  • Play-Slick Plugin 0.5.0.8

Trả lời

4

Hầu. Bạn có thể xác định một giá trị mặc định với một lựa chọn như thế này:

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

Nếu bạn chắc chắn không muốn một lựa chọn, bạn có thể có một cái nhìn ở đây:

Defaults for missing properties in play 2 JSON formats

+0

Xin chào, cảm ơn tôi không muốn có tùy chọn. Đối với liên kết bạn đã cung cấp. Người dùng nói rằng giải pháp hiện tại của anh ta có một số nhược điểm và tôi phải nói rằng tôi đồng ý. Tuy nhiên nếu không có giải pháp tốt hơn được đề nghị tôi sẽ kết thúc bằng cách sử dụng cách tiếp cận của mình như tôi không thấy một cách xung quanh – ufasoli

+0

Giải pháp tốt nhất sẽ liên quan đến việc viết một macro để tự động tạo withDefault, đây là khá thực hiện mặc dù: ( – Jean

+0

) khá nhiều nỗ lực ... – ufasoli

1

Một workaround sẽ được để viết một phương pháp áp dụng giá trị mặc định được tính là một tùy chọn và xử lý việc xây dựng (không thể đặt tên cho nó khi chúng tôi cần một tên rõ ràng khi xây dựng các Đọc của chúng tôi):

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

Sau đó, bạn có thể sử dụng readNullable cho giá trị mặc định, mà sẽ vượt qua một lựa chọn [Int] để applyOpt:

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

Chắc chắn không phải lý tưởng, đặc biệt là nếu bạn có một vài lĩnh vực mặc định, nhưng một workaround nhanh chóng mà tránh được việc phải đối phó với các macro hoặc sự phản chiếu.

+0

có nhưng tôi đã hy vọng tránh viết trình đọc với tất cả các trường như có nhiều lớp chữ với cùng một trường hợp nhưng nhiều trường khó đọc và dễ bị lỗi khi mô hình chưa 100% ổn định và bạn cần phải cập nhật nó, tôi đã hy vọng nó sẽ chỉ làm việc ra khỏi hộp như Jackson hiện trong Java – ufasoli

Các vấn đề liên quan