Play Scala No Json deserializer found for type (String, String)。尝试为这种类型实现隐式读取或格式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16183798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:13:14  来源:igfitidea点击:

Play Scala No Json deserializer found for type (String, String). Try to implement an implicit Reads or Format for this type

scalaplayframework

提问by Steve Wagner

These Json serializers in Play with Scala are driving me nuts.

Play with Scala 中的这些 Json 序列化器让我抓狂。

I have read dozens of posts and the tutorials and the documentation. Tried four different ways of implementing Reads / Writes / Format overrides and all to no avail.

我已经阅读了数十篇文章、教程和文档。尝试了四种不同的实现读取/写入/格式覆盖的方法,但都无济于事。

So I backed off the custom type and decided to go uber simple:

所以我放弃了自定义类型并决定变得超级简单:

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

And the error comes back as noted in the subject.

如主题中所述,错误又回来了。

Do I reallyneed to provide a custom Reads / Writes / Format implementation for such a basic body?

真的需要为这样的基本体提供自定义的读取/写入/格式实现吗?

A sample input body could be:

示例输入主体可以是:

{"suggestion":"add generics", "categories":"request;language;updates"}

What simple thing am I missing?

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

回答by sthomps

Play! gives you a LOT of ways to work with Json. From the looks of your code, you're going down the Tuple road. Which essentially lets you convert Json into a Tuple. You're also using 'reads' which has the downside that you don't get preciseerror reporting (ie: if invalid json was passed you would know its invalid... but you wouldn't necessarily know whyit was invalid). If you wanted more error handling then you need to start using the 'validate' method (details here: http://www.playframework.com/documentation/2.1.1/ScalaJsonCombinators).

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

Another way you could go is to map Json to case classes doing something like:

您可以采用的另一种方法是将 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)
    }
  }
}

This seems like a lot of code so Play 2.1 introduced Json 'Inception' which I have yet to try (http://www.playframework.com/documentation/2.1.1/ScalaJsonInception).

这似乎有很多代码,所以 Play 2.1 引入了 Json 'Inception',我还没有尝试过(http://www.playframework.com/documentation/2.1.1/ScalaJsonInception)。

Finally, if you want the Json validation but don't necessary need to marshall/unmarshall case classes, then you can try the 'coast-to-coast' method. This will keep all your json as JsObject types but still give you validation. Sample code here: https://github.com/mandubian/play2-json-demo/blob/master/json-coast-to-coast/app/controllers/Application.scala

最后,如果您想要 Json 验证但不需要编组/解组案例类,那么您可以尝试“海岸到海岸”方法。这会将您的所有 json 保留为 JsObject 类型,但仍会为您提供验证。这里的示例代码:https: //github.com/mandubian/play2-json-demo/blob/master/json-coast-to-coast/app/controllers/Application.scala

Hope this helps.

希望这可以帮助。

回答by Steve Wagner

So I added this:

所以我添加了这个:

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

And that seems to work.

这似乎有效。

Curious, though, is this really the best way to do this? It seems like a LOT of code if you have many many types to serialize / deserialize.

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