Работа с JSON является очень распространенной задачей в процессе разработки программного обеспечения. В Scala вы можете сделать это разными способами, либо с помощью популярных библиотек Java, таких как Jackson, или с помощью специальных библиотек Scala. Как сделать правильный выбор из Spray JSON, Play JSON , Argonaut, Jackson, Rapture и многих других?
Однажды я получил тестовое задание на собеседовании. В соответствии с этим мне пришлось реализовать сериализацию и десериализацию JSON объекта Checkout в контексте электронной коммерции. Я проанализировал все существующие библиотеки JSON для Scala, я использовал каждую из них для небольших выборок и решил взять библиотеку Play JSON для этой задачи. Я сделал это, потому что у него есть исчерпывающая документация, много примеров, это часть самой популярной веб-платформы Scala, и мне нравится ее API.
Вопрос заключался в том, как использовать JSON-модуль PlayFramework без всего фреймворка. И я нашел отдельный репозиторий git с API Play JSON.
Для тех из вас, кто хочет увидеть, как использовать модуль Play JSON отдельно от Play Framework, я продолжу этот пост.
Как использовать модуль Play JSON?
Во-первых, вам нужно добавить библиотеку Play JSON в ваш проект. Вы можете сделать это различными способами — скачать код библиотеки и включить его в проект или использовать какой-либо инструмент управления зависимостями. Лично я использую SBT в проектах Scala.
Вот как мы можем добавить зависимость Play JSON в файл SBT:
1
2
3
4
5
6
7
|
name := "proectj-name" version := "1.0" scalaVersion := "2.11.7" libraryDependencies ++ = Seq( "com.typesafe.play" % "play-json_2.11" % "2.4.2" ) |
Тогда вы, вероятно, захотите посмотреть, как сериализация и десериализация JSON могут выполняться с помощью этой библиотеки. Что ж, давайте сделаем короткую демонстрацию. Вот модель JSON, и нам нужно работать с ней:
01
02
03
04
05
06
07
08
09
10
11
12
|
{ "id" : 1 , "type" : "credit card" , "address" : { "address1" : "Baker str 3" , "address2" : "" , "city" : "London" , "zipcode" : "WC064" }, "token" : "u4lPaa74M" "cvv" : 112 } |
Это часть модели Checkout — оплата. Что нам нужно сделать сначала, чтобы реализовать сериализацию и десериализацию для этой модели JSON?
- Создайте модель Scala для самой глубокой модели в JSON. Вот класс случая для поля Address:
12345
case
class
Address(address
1
:
String,
address
2
:
Option[String],
city
:
String,
state
:
String,
zipcode
:
String)
- Объявите правила записи и чтения , которые используются для записи модели Scala в JSON и для чтения JSON в Scala. Эта логика может быть объявлена в объекте Address:
010203040506070809101112131415
object
Address {
import
play.api.libs.json.
_
implicit
val
addressFormats
=
Json.format[Address]
def
writeAddress(address
:
Address)
=
{
Json.toJson(address)
}
def
readAddress(jsonAddress
:
JsValue)
=
{
jsonAddress.as[Address]
}
}
Как видите, мы используем объект Play Json , чтобы выполнить сериализацию и десериализацию объекта с простыми полями. Под простыми я подразумеваю строки, числа, массивы и нулевые значения.
- Выполните действия № 1, № 2 для родительского объекта.
010203040506070809101112131415161718192021222324252627282930
case
class
Payment(id
:
Long,
pType
:
String,
address
:
Address,
token
:
String,
cvv
:
String)
object
Payment {
import
play.api.libs.json.
_
def
writePayment(payment
:
Payment)
=
{
JsObject(Seq(
"id"
-> JsNumber(payment.id),
"type"
-> JsString(payment.pType),
"address"
-> Json.toJson(payment.address),
"token"
-> JsString(payment.token),
"cvv"
-> JsString(payment.cvv)
))
}
def
readPayment(jsonPayment
:
JsValue)
=
{
val
id
=
(jsonPayment \
"id"
).as[Long]
val
pType
=
(jsonPayment \
"type"
).as[String]
val
address
=
(jsonPayment \
"address"
).as[Address]
val
token
=
(jsonPayment \
"token"
).as[String]
val
cvv
=
(jsonPayment \
"cvv"
).as[String]
Payment(id, pType, address, token, cvv)
}
}
Мы получили более подробный код выше, это связано с именем поля типа . Поскольку слово типа зарезервировано в Scala, мы не можем использовать его как имя переменных в Scala. Таким образом, мы должны определить чтение и запись вручную для модели Payment.
Как проверить сериализацию и сериализацию в Scala?
Чтобы проверить, что все работает нормально, мы можем создать модульные тесты. Добавьте зависимость ScalaTest в файл SBT. Теперь это должно выглядеть так:
1
2
3
4
5
6
7
8
9
|
name := "proectj-name" version := "1.0" scalaVersion := "2.11.7" libraryDependencies ++ = Seq( "org.scalatest" % "scalatest_2.11" % "3.0.0-SNAP5" % "test" , "com.typesafe.play" % "play-json_2.11" % "2.4.2" ) |
И напишите тесты для оплаты:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
import models. _ import models.Payment. _ import org.scalatest. _ import play.api.libs.json. _ class PaymentTest extends FlatSpec with Matchers { val address = Address( "1375 Burlingame Ave." , None, "Burlingame" , "California" , "94010" ) "Payment " should "be converted to JSON correctly " in { val payment = Payment( 1 , "creditCard" , address, "wdweadowei3209423" , "123" ) val paymentJSON = writePayment(payment) (paymentJSON \ ( "id" )).get should be (JsNumber( 1 )) (paymentJSON \ ( "type" )).get should be (JsString( "creditCard" )) (paymentJSON \ ( "address" )).get should be (Json.toJson(payment.address)) (paymentJSON \ ( "token" )).get should be (JsString( "wdweadowei3209423" )) (paymentJSON \ ( "cvv" )).get should be (JsString( "123" )) } it should " be deserialized correctly " in { val paymentJSON : JsValue = JsObject(Seq( "id" -> JsNumber( 1 ), "type" -> JsString( "creditCard" ), "address" -> Json.toJson(address), "token" -> JsString( "wdweadowei3209423" ), "cvv" -> JsString( "123" ) )) val payment = readPayment(paymentJSON) payment.id should be ( 1 ) payment.pType should be ( "creditCard" ) payment.address should be (address) payment.token should be ( "wdweadowei3209423" ) payment.cvv should be ( "123" ) } } |
Резюме
Модуль JSON Play действительно мощный. Я не описал много вещей, которые можно сделать с его помощью. Но я рекомендую вам прочитать официальную документацию и посмотреть другие примеры. Обратите особое внимание на версии документов, которые вы читаете, и Scala, которые вы используете в проекте.
Ссылка: | Scala: работа с JSON от нашего партнера JCG Алексея Зволинского в блоге заметок Фрузенштейна . |