13

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

我错过了什么简单的事情?

4

2 回答 2

6

玩!为您提供了很多使用 Json 的方法。从您的代码的外观来看,您正在走元组之路。这基本上可以让您将 Json 转换为元组。您还使用了“读取”,它的缺点是您无法获得精确的错误报告(即:如果传递了无效的 json,您会知道它是无效的……但您不一定知道它为什么无效)。如果您想要更多的错误处理,那么您需要开始使用“验证”方法(详情请点击此处: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

希望这可以帮助。

于 2013-04-27T03:19:38.740 回答
2

所以我添加了这个:

  implicit val rds = (
    (__ \ 'suggestion).read[String] and
    (__ \ 'categories).read[String]
  ) tupled

这似乎奏效了。

不过,好奇的是,这真的是最好的方法吗?如果您有许多类型要序列化/反序列化,这似乎是一大堆代码。

于 2013-04-24T05:22:23.460 回答