gpt4 book ai didi

json - 在 Play 中将 Seq 映射到 JSON

转载 作者:行者123 更新时间:2023-12-03 22:32:53 25 4
gpt4 key购买 nike

我正在尝试使用 Play 2.x 将 Scala 案例类映射到 JSON。这适用于 case 类的简单版本,但不适用于涉及 Seq 或 List 的对象:然后我得到“没有隐式格式”和“没有找到未应用的函数”错误。

我为此使用的代码如下:

case class Book(title: String, authors: Seq[Author])
case class Author(name: String)

我用过 Json.format用于为此生成读取和写入的宏:
implicit val bookFormat = Json.format[Book]
implicit val authorFormat = Json.format[Author]

但是现在当我编译我的代码时,我收到以下错误:
Error:(25, 40) Play 2 Compiler: 
/Users/erikp/Userfiles/projects/play/booksearch/app/models/user.scala:25: No implicit format for Seq[models.Author] available.
implicit val bookFormat = Json.format[Book]
^

没有 Seq 它可以很好地工作,但是有了 Seq,它就失败了。我尝试添加 implicit val authorsFormat = Json.format[Seq[Author]]到隐式转换器,但这没有效果。

最佳答案

为图中需要序列化的每个类定义符合其依赖顺序的格式化程序。

格式化 Book需要格式化 Author ,所以定义 Author Book 之前的格式化程序格式化程序。

例如,有了这个 Models.scala文件:

package models

import play.api.libs.json._

case class Book(title: String, authors: Seq[Author])
case class Author(name: String)

object Formatters {
implicit val authorFormat = Json.format[Author]
implicit val bookFormat = Json.format[Book]
}

而这个 JsonExample.scala文件:
package controllers

import models._
import models.Formatters._
import play.api.mvc._
import play.api.libs.json._

object JsonExample extends Controller {

def listBooks = Action {
val books = Seq(
Book("Book One", Seq(Author("Author One"))),
Book("Book Two", Seq(Author("Author One"), Author("Author Two")))
)
val json = Json.toJson(books)
Ok(json)
}

}

listBooks 的请求会产生这样的结果:

< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Content-Length: 133
<
[{"title":"Book One","authors":[{"name":"Author One"}]},{"title":"Book Two","authors":[{"name":"Author One"},{"name":"Author Two"}]}]

有关更高级的格式化,包括部分序列化以避免必须为不应序列化的类声明格式化程序,请参阅 JSON Reads/Writes/Format Combinators .

应该记住,要序列化的类不一定是域模型类。声明反射(reflect)所需 JSON 结构的数据传输对象 (DTO) 类并从域模型中实例化它们可能会有所帮助。这样,序列化很简单, Json.format并且不存在部分序列化的问题,还有 JSON API 的类型安全表示的额外好处。

例如,这个 BookDTO.scala文件定义了一个 BookDTO仅使用可序列化为 JSON 的类型而无需进一步定义的数据传输对象:
package dtos

import models._
import play.api.libs.json.Json

case class BookDTO (title: String, authors: Seq[String])

object BookDTO {

def fromBook(b: Book) = BookDTO(b.title, b.authors.map(_.name))

implicit val bookDTOFormat = Json.format[BookDTO]

}

而这个 JsonExample2.scala文件显示了如何使用此模式:
package controllers

import dtos._
import dtos.BookDTO._
import models._
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.functional.syntax._

object JsonExample2 extends Controller {

def listBooks = Action {
val books = Seq(
Book("Book One", Seq(Author("Author One"))),
Book("Book Two", Seq(Author("Author One"), Author("Author Two")))
)
val booksDTO = books.map(BookDTO.fromBook(_))
Ok(Json.toJson(booksDTO))
}

}

关于json - 在 Play 中将 Seq 映射到 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24498740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com