Ответ 1
В настоящее время у Play есть много новых возможностей для JSON. Это была бы приятная витрина для свойства Format[A]
(см. Scala Json Inception), которую вы могли бы включить неявно, как я покажу, или явно для методов, которым требуется неявный Format[A]/Reads[A]/Writes[A]
.
Создайте класс case для представления ваших объектов JSON,
case class Book(id: Int, name: String)
case class BookDetail(id: Int, author: String, publicationDate: Int, pages: Int)
Создайте объекты сопутствующих объектов, которые содержат неявный Format[A]
так что Format/Reads/Writes
автоматически попадет в область действия по мере необходимости.
object Book {
implicit val fmt: Format[Book] = Json.format[Book]
}
object BookDetail {
implicit val fmt: Format[BookDetail] = Json.format[BookDetail]
}
Теперь вы можете сделать что-то подобное,
val bookJson = Json.toJson(Book(1, "A Brief History Of Time"))
val bookDetailJson = Json.toJson(BookDetail(1, "Steven Hawking", 1988, 256))
bookJson.as[JsObject].deepMerge(bookDetailJson.as[JsObject])
И у вас будет такой объект,
{
id: 1,
name: "A Brief History Of Time",
author: "Steven Hawking",
publicationDate: 1988,
pages: 256
}
Я пробовал это в REPL, но это не сработает, в Play Play оно все равно прекрасно. Также в сценарии производства мы, скорее всего, будем использовать asOpt[T]
вместо as[T]
.
Вот пример того, почему asOpt[T]
может быть лучше подходит, предположим вместо действительного объекта JSON для книги, которую вы получаете,
val bookJson = Json.toJson("not a book")
В итоге вы получите
[JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsobject,WrappedArray())))))]
Но предположим, что вместо этого вы измените свой метод на использование asOpt[T]
,
bookJson.asOpt[JsObject].getOrElse(Json.obj()).deepMerge(bookDetailJson.asOpt[JsObject].getOrElse(Json.obj()))
Теперь у вас будет, по крайней мере, частичный объект JSON,
{
id: 1,
author: "Steven Hawking",
publicationDate: 1988,
pages: 256
}
Таким образом, в зависимости от того, как вы хотели бы обрабатывать неправильно отформатированный JSON, вы можете выбрать любой вариант.