Play with Scala中的这些Json序列化程序让我疯狂。
我已阅读了数十篇帖子以及教程和文档。尝试了四种不同的实现读/写/格式覆盖的方法,但都无济于事。
所以我退出了自定义类型并决定简单地使用:
def suggest = Action(parse.json) {
request =>
request.body.validate[(String, String)].map {
case (suggestion, categories) => Ok("You suggested " + suggestion + " for categories " + categories)
}.recoverTotal {
e => BadRequest(JsError.toFlatJson(e))
}
}
如上所述,错误会再次出现。
我真的是否需要为这样的基本身体提供自定义的读/写/格式实现?
示例输入正文可以是:
{"suggestion":"add generics", "categories":"request;language;updates"}
我错过了什么简单的事情?
答案 0 :(得分:6)
播放!为您提供了很多与Json合作的方法。从代码的外观来看,你正沿着Tuple路走下去。这本质上允许您将Json转换为元组。您还使用“读取”,其缺点是您没有精确错误报告(即:如果通过了无效的json,您将知道其无效......但您不一定知道为什么它无效)。如果您想要更多的错误处理,那么您需要开始使用'validate'方法(详情请参阅:http://www.playframework.com/documentation/2.1.1/ScalaJsonCombinators)。
另一种方法是将Json映射到案例类,例如:
import play.api.libs.json._
case class MyClass(
suggestion: String,
categories: String
)
object MyClass {
implicit val readsMyClass: Reads[MyClass] = new Reads[MyClass] {
def reads(json: JsValue): JsResult[MyClass] = {
for {
suggestion <- (json \ "suggestion").validate[String]
categories <- (json \ "categories").validate[String]
} yield MyClass(json,categories)
}
}
}
这看起来像很多代码所以Play 2.1引入了Json'Inception',我还没试过(http://www.playframework.com/documentation/2.1.1/ScalaJsonInception)。
最后,如果您想要Json验证但不需要编组/解组案例类,那么您可以尝试“沿海岸到海岸”方法。这将使您的所有json保持为JsObject类型,但仍然为您提供验证。示例代码:https://github.com/mandubian/play2-json-demo/blob/master/json-coast-to-coast/app/controllers/Application.scala
希望这有帮助。
答案 1 :(得分:2)
所以我补充说:
implicit val rds = (
(__ \ 'suggestion).read[String] and
(__ \ 'categories).read[String]
) tupled
这似乎有效。
但是,好奇,这真的是最好的方法吗?如果您有许多类型来序列化/反序列化,似乎有很多代码。