Java >> Tutorial de Java >  >> Tag >> Json

¡Tocar! Ejemplo de Framework JSON y Scala

En esta publicación, presentamos un ejemplo completo en Play! Framework JSON y Scala. En mis últimas dos publicaciones, hemos discutido sobre los conceptos básicos del proyecto basado en Play Framework + Scala + SBT. Consulte Jugar! Framework Hello World Ejemplo y ¡Juega! Ejemplo de parámetros predeterminados de ruta, consulta y ruta del marco para comprender la estructura del proyecto Play + SBT, las configuraciones del proyecto, las configuraciones SBT, etc. ¡Esta es mi tercera publicación en Play! Serie de tutoriales de Framework.

En mi publicación anterior, hemos discutido los conceptos básicos de Play Framework con el ejemplo de HelloWorld. Espero que hayas experimentado ese ejemplo y que estés esperando el siguiente paso en esta serie. Si no lo ha hecho, ¡es mejor revisar mi publicación anterior primero en Play! Ejemplo de Framework Hello World para comprender la estructura del proyecto Play + Scala + SBT y los conceptos básicos de Play Framework.

En esta publicación, vamos a discutir sobre uno de los módulos importantes de Play! Marco:Módulo Play JSON con algunos ejemplos simples y útiles.

Índice

1. Introducción
2. Tecnologías utilizadas
3. Juega los conceptos básicos de la API de JSON
3.1 Utilidades Json
3.2 Utilidades JsPath
4. Juega al convertidor de lecturas JSON
5. Juega al convertidor de escrituras JSON
6. Juega al convertidor de formato JSON
7. Ejemplo de Play JSON Scala HelloWorld
7.1 Ejemplo de reproducción de prueba JSON HelloWorld
7.2 Reproducir JSON HelloWorld sin Json.toJson
7.3 Ejemplo de Play JSON HelloWorld con vista de plantilla
8. Ejemplo complejo de Play JSON Scala
9. Conclusión
10. Referencias
11. Descarga el código fuente

1. Introducción

¡Tocar! Framework es un marco web MVC moderno basado en REST y Moulder de alta productividad. Por diseño, es compatible con el desarrollo de la API REST utilizando JSON sobre el protocolo HTTP. JSON es un tipo de Transferencia de datos o Intercambio de datos que es Tipo de contenido.

JSON significa Notación de objetos de JavaScript. Si es nuevo en el formato de datos JSON, vaya a http://json.org sitio web para aprender algunos conceptos básicos.

Para admitir la conversión entre Scala Object y JSON, Play Framework tiene un módulo separado:Módulo Play JSON . Es uno de los módulos importantes y más utilizados de Play! Estructura.

Si quieres pasar por el Play! Código fuente de la API JSON, consulte esta URL de GitHub:https://github.com/playframework/play-json

La biblioteca Play JSON tiene dos tipos de API:una API para Java y otra para Scala. En esta publicación, nos concentraremos solo en Play JSON Scala API.

2. Tecnologías utilizadas

En esta publicación, vamos a utilizar las siguientes tecnologías:

  • Scala 2.12.6
  • Marco de juego 2.6.17
  • Reproducir JSON 2.6.9
  • SBT 1.1.5
  • IDEA de IntelliJ

Antes de explorar los próximos pasos, intente instalar Java 1.8 o una versión posterior y el software mencionado anteriormente. Comencemos a desarrollar nuestra primera aplicación web Play Scala en la siguiente sección.

3. Juega los conceptos básicos de la API de JSON

¡Tocar! Framework admite la API de JSON como un módulo separado y su nombre es play-json . La API Play JSON completa se definió en play.api.libs.json paquete en este módulo. Las versiones iniciales de Play Framework tienen esta API JSON dentro del módulo central principal, por lo que debería estar disponible solo para Play Framework. Posteriormente, movieron esta API a un módulo separado para que podamos usarla tanto para proyectos basados ​​en el juego como para proyectos no basados ​​en el juego.

JSON es un formato ligero de intercambio de datos basado en texto sin formato. Es un formato de datos independiente del idioma, la plataforma (sistema operativo) y el protocolo.

El objetivo principal de Play JSON API es proporcionar una API compatible con las siguientes características:

  • Convertir objeto Scala en objeto JSON
  • Convertir objeto JSON en objeto Scala
  • Otras utilidades JSON

Si queremos usar este módulo Play JSON en nuestro proyecto, debemos agregar la siguiente dependencia de biblioteca en nuestro build.sbt archivo como se muestra a continuación:

1 libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.9"

Al igual que Java o Scala tienen tipos de datos para representar valores, Play JSON API también tiene los siguientes tipos de datos para representar todos y cada uno de los tipos de datos JSON.

  • Cadena Js :Representa un valor de cadena Json.
  • Número Js :Representa un valor numérico Json.
  • Booleano Js :Representa un valor booleano Json.
  • JsObjeto :Representa un valor de objeto Json.
  • JsArray :representa un valor de matriz Json.
  • JsNulo :representa un valor nulo de Json.

Todos estos tipos de datos tienen un súper componente:JsValue y todos están organizados como se muestra en el siguiente diagrama:

Reproducir tipos de datos JSON

Hablaremos sobre las lecturas, escrituras y formatos de la API Play JSON en las próximas secciones. Además de estas API, Play JSON API tiene algunas otras utilidades para admitir funcionalidades JSON adicionales como Json, JsPath, etc.

3.1 Utilidades Json

Al igual que otras API de Play JSON, Json también se define en play.api.libs.json paquete. Proporciona algunas utilidades, que son principalmente útiles para convertir hacia y desde JsValue estructuras Contiene funciones auxiliares para manejar JsValues.

Json.toJson(): Para convertir un objeto Scala a JsValue, debemos usar Json.toJson() utilidad como se muestra a continuación:

12 import play.api.libs.json._ Json.toJson(HelloWorld( "Json" ))

Aquí HelloWorld es una clase de Scala Case, que toma un String como parámetro. Cuando pasamos este objeto a Json.toJson() utilidad, convertirá ese objeto Scala en JsValue como se muestra a continuación:

Json.stringify(): Para representar un JsValue como una cadena, debemos usar Json.stringify() utilidad como se muestra a continuación:

12 import play.api.libs.json._ Json.stringify(Json.toJson(HelloWorld( "Json" )))

Aquí primero convertimos nuestro HelloWorld clase de caso en un JsValue usando Json.toJson() función. Luego convertimos este JsValue en una cadena usando Json.stringify() función.

analizar(): Es todo lo contrario a la función Json.stringify(). Para representar una Cadena como un JsValue, debemos usar Json.parse() utilidad como se muestra a continuación:

1234567 import play.api.libs.json._ val json: JsValue = Json.parse( "" "    {      "module" : "json" ,    }    "" ")

Aquí Scala String representa nuestro HelloWorld clase de caso en formato de cadena. Luego estamos convirtiendo ese objeto Scala String en un JsValue usando Json.parse() función.

3.2 Utilidades JsPath

Al igual que otras API de Play JSON, JsPath también se define en play.api.libs.json paquete. JsPath representa una ruta a una estructura JsValue. Al igual que usamos XPath para atravesar documentos XML, podemos usar JsPath para atravesar objetos JSON. Lo utilizaremos ampliamente para escribir convertidores implícitos de lecturas, escrituras y formatos.

Por ejemplo, tenemos la siguiente cadena JSON para representar nuestro HelloWorld clase de caso en formato String.

1234567 import play.api.libs.json._ val json: String = "" "    {      "module" : "json" ,    }    "" "

Luego podemos acceder a la propiedad "módulo" o la ruta a la propiedad "módulo" es como se muestra a continuación:

1 JsPath \ "module"

Supongamos que tenemos la propiedad del submolde en la propiedad del módulo, luego podemos acceder a la propiedad del "submódulo" como se muestra a continuación:

1 JsPath \ "module" \ "submodule"

JsPath es un componente básico para escribir convertidores manuales de lectura/escritura/formato. Exploraremos en profundidad "Cómo escribir convertidores manuales y cómo usar estas funciones auxiliares o utilidades" en las próximas secciones de ejemplos.

Play JSON API tiene los siguientes tres convertidores diferentes para convertir JsValue a Scala Value (u Scala Object) y viceversa:

  • Convertidor de LECTURAS
  • Convertidor de ESCRITURAS
  • Convertidor de FORMATO

Usemos la siguiente clase de caso para explorar estos tres convertidores.

HolaMundo.scala

1 case class HelloWorld(module:String, submodule:String)

Discutiremos estos convertidores en detalle en las próximas secciones con algunos ejemplos útiles.

4. Juega al convertidor de lecturas JSON

En Play JSON API, los convertidores de lectura se utilizan para convertir un JsValue en un valor (en palabras específicas, es un valor de Scala, un objeto de Scala o un tipo de Scala). Reads también se define como un rasgo en play.api.libs.json paquete.

Aquí también podemos usar otras palabras en lugar de la palabra "convertir". Decodifica, deserializa o convierte un JsValue en un valor de Scala, como se muestra en el siguiente diagrama.

Juega al convertidor de lecturas JSON

Entonces, el convertidor de lecturas también se conoce como "Deserializador", ya que deserializa un tipo JSON (JsValue) a un valor Scala.

Por lo general, escribimos lecturas como objetos implícitos. Cuando nuestro programa encuentra que Lee el objeto implícito en el alcance, nuestro programa decodificará ese JSON en un tipo correcto.

Lecturas automáticas para el tipo HelloWorld:

1 implicit val reads = Json.reads[HelloWorld]

Esto se llama "Mapeo automatizado JSON ” para Lecturas. No necesitamos preocuparnos por mapear todas y cada una de las propiedades de una clase de caso con el tipo de propiedad. Si tenemos algún requisito específico o Play Framework NO realiza el mapeo automático para sus tipos, entonces podemos usar "Asignación manual JSON " Como se muestra abajo:

Lecturas manuales para el tipo HelloWorld:

1234 implicit val reads:Reads[HelloWorld] = (    (JsPath \ "module" ).read[String] and    (JsPath \ "submodule" ).read[String] )(HelloWorld.apply)

Aquí hemos mapeado ambos HelloWorld propiedades de clase de caso con tipo de datos de propiedad de cadena. Como se discutió en la sección anterior, usamos las utilidades JsPath y "\" para recorrer cada propiedad.

Deberíamos especificar HelloWorld.apply función para leer cada propiedad una por una del objeto JSON dado y crear un objeto de tipo HelloWorld.

5. Juega al convertidor de escrituras JSON

En Play JSON API, los convertidores de escritura se utilizan para convertir un valor (en palabras específicas, es un valor de Scala, un objeto de Scala o un tipo de Scala) en un JsValue. Writes también se define como un rasgo en play.api.libs.json paquete.

Aquí también podemos usar otras palabras en lugar de la palabra "convertir". Codifica, serializa o convierte un valor de Scala en un JsValue como se muestra en el siguiente diagrama.

Juega al convertidor de escrituras JSON

Por lo tanto, el convertidor de escritura también se conoce como "Serializador", ya que serializa un valor de Scala en un tipo JSON (JsValue).

Al igual que las lecturas, generalmente escribimos las escrituras como objetos implícitos. Cuando nuestro programa encuentra que escribe un objeto implícito en el alcance, nuestro programa codificará ese tipo de Scala en un JSON.

Escrituras automáticas para el tipo HelloWorld:

1 implicit val writes = Json.writes[HelloWorld]

Esto se llama "Mapeo automatizado JSON ” para Escribe. También podemos escribir “Asignación manual JSON " Como se muestra abajo:

Escrituras manuales para el tipo HelloWorld:

1234 implicit val writes:Writes[HelloWorld] = (    (JsPath \ "module" ).write[String] and    (JsPath \ "submodule" ).write[String] )(unlift(HelloWorld.unapply))

Aquí hemos mapeado ambos HelloWorld propiedades de clase de caso con tipo de datos de propiedad de cadena. Deberíamos especificar HelloWorld.unapply función para extraer todas y cada una de las propiedades de tipo HelloWorld en un objeto JSON. Hasta ahora bien, usamos apply función para Lecturas y unapply función para escrituras. ¿Qué pasa con ese "desencauzar “? ¡Buena pregunta! 😊

Discutámoslo ahora.

En primer lugar, suponga que nuestro HelloWorld la clase de caso se guarda en el archivo HelloWorld.scala. Compílelo, luego observe el código Java generado como se muestra a continuación (extraído solo el fragmento de código requerido):

123456 public class HelloWorld implements Product, Serializable {    // Other code    public static Option<Tuple2> unapply(HelloWorld);    public static HelloWorld apply(String, String);    // Other code }

Aquí podemos observar que nuestro HelloWorld la clase de caso contiene ambos apply y unapply funciones Como sabemos, HelloWorld La clase case contiene dos propiedades y ambas son de tipo String.

Bueno, apply la función toma los tipos de parámetros correctos:Cadena, Cadena como HelloWorld apply(String, String) . Sin embargo, si observamos el tipo de retorno o tipo de resultado de unapply función, NO es una cadena, una cadena como Option<Tuple2> unapply(HelloWorld) . Está regresando la opción de (String,String), pero debería ser (String,String) para que funcione. Escribe el convertidor correctamente con unapply función. Para eliminar este Option adicional tipo, usamos unlift función disponible en el objeto del paquete play.api.libs.funcional.syntax.

Espero que lo entiendas muy bien.

6. Juega al convertidor de formato JSON

En Play JSON API, los convertidores de formato se utilizan para convertir un JsValue en un tipo Scala o viceversa (es decir, de un tipo Scala a un JsValue). En palabras simples, el convertidor de formato Play JSON contiene convertidores de lectura y escritura, es decir, formato =lectura + escritura, como se muestra a continuación.

Reproducir formato JSON =Lecturas + Escrituras

De otra manera, podemos representar este convertidor de formato como se muestra a continuación:

Juega al convertidor de formato JSON

Como lecturas y escrituras, Format también se define como un rasgo en play.api.libs.json paquete.

Aquí también podemos usar otras palabras en lugar de la palabra "convertir". Codifica y decodifica o serializa y deserializa o convierte un tipo Scala a un JsValue y viceversa, como se muestra en el siguiente diagrama.

Al igual que las lecturas y las escrituras, generalmente escribimos formato como objetos implícitos. Cuando nuestro programa encuentra ese objeto implícito Format en el alcance, nuestro programa codificará ese tipo Scala en un JSON o decodificará un JSON en un tipo Scala.

Formato automático para el tipo HelloWorld:

1 implicit val format = Json.format[HelloWorld]

Formato manual para tipo HelloWorld:

1234 implicit val format: Format[HelloWorld] = (      (JsPath \ "module" ).format[String] and      (JsPath \ "submodule" ).format[String]    )(HelloWorld.apply, unlift(HelloWorld.unapply))

Como el formato es una mezcla de lecturas y escrituras, hemos definido nuestro objeto implícito de formato usando tanto apply y unapply funciones

A veces, si tenemos objetos implícitos de lectura y escritura por separado, como se muestra a continuación:

Lecturas manuales para el tipo HelloWorld:

1234 implicit val readsHelloWorld: Reads[HelloWorld] = (      (JsPath \ "module" ).read[String] and      (JsPath \ "submodule" ).read[String]    )(HelloWorld.apply)

Escrituras manuales para el tipo HelloWorld:

1234 implicit val writesHelloWorld: Writes[HelloWorld] = (      (JsPath \ "module" ).write[String] and      (JsPath \ "submodule" ).write[String]    )(unlift(HelloWorld.unapply))

entonces podemos escribir convertidor de formato como se muestra a continuación:

Formato manual para el tipo HelloWorld usando lecturas y escrituras:

1 implicit val format: Format[HelloWorld] = Format[readsHelloWorld, writesHelloWorld]

El play.api.libs.json El paquete define un alias para JsPath:__ (doble guión bajo). Podemos usar esto si lo preferimos:

1234 implicit val writesHelloWorld: Writes[HelloWorld] = (      (__ \ "module" ).write[String] and      (__ \ "submodule" ).write[String]    )(unlift(HelloWorld.unapply))

NOTA: En la publicación, para definir los convertidores, he usado "Valor" como valor de Scala. Pero puede ser cualquier cosa según el lenguaje que usemos. Por ejemplo, si los usamos en Java, este “Valor” significa “Valor de Java”.

Eso es todo sobre tres Convertidores o Combinadores de Play Framework. El código fuente de Play Framework los definió como Macros.

7. Ejemplo de reproducción de JSON Scala HelloWorld

Hasta ahora, hemos discutido la teoría suficiente sobre la teoría del módulo Play JSON. Es hora de comenzar a desarrollar un ejemplo simple y básico de HelloWorld utilizando Play Framework, Play JSON Module y Scala.

Vamos a utilizar la herramienta de compilación IntelliJ IDE y SBT para desarrollar esta aplicación. Si está utilizando IntelliJ IDE Ultimate Edition, primero cree una aplicación web Play Framework utilizando IDE. Si está utilizando IntelliJ IDE CE (Community Edition), descargue el proyecto Play Scala Starter desde la siguiente ubicación de GitHub de Lightbend's Play Framework Examples:
https://github.com/playframework/play-scala-starter-example

Cambié el nombre de este proyecto como "PlayJSONScalaHelloWorldExample", lo importé a IntelliJ IDE y eliminé todos los archivos.

Luego, continúe con los siguientes pasos para desarrollar nuestra aplicación HelloWorld:

    • Agregue el complemento SBT Play Framework al archivo "plugins.sbt" como se muestra a continuación:

complementos.sbt

1 addSbtPlugin( "com.typesafe.play" % "sbt-plugin" % "2.6.17" )

En mis dos publicaciones anteriores, estaba usando la versión "2.6.13" del complemento SBT de Play Framework. Siga el blog de Play Framework en https://blog.playframework.com para actualizaciones periódicas.

    • Agregue la dependencia de la biblioteca Play JSON en el archivo "build.sbt" como se muestra a continuación:

construir.sbt

0102030405060708091011 name := "PlayJSONScalaHelloWorldExample" version := "1.0.0" lazy val root = (project in file( "." )).enablePlugins(PlayScala) scalaVersion := "2.12.6" libraryDependencies ++= Seq(guice) libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.9"

Descripción:

      • Play Framework tiene su módulo JSON con el nombre "play-json"
      • La última versión actual es 2.6.9
      • Necesitamos agregar las dependencias de la biblioteca de nuestro proyecto a libraryDependencies SBT variable
    • Agregue una ruta de reproducción al archivo de "rutas" como se muestra a continuación:

rutas

12 ## Hello Play JSON Controller GET   /hello/:module  controllers.HelloWorldJSONController.hello(module: String)

Aquí hemos mapeado el URI “/hello/:module” a HelloWorldJSONController.hello función. Eso significa que cuando el usuario accede a nuestra aplicación con algo como http://localhost:9000/hello/json , esa solicitud es atendida por este hello función.

    • Desarrolla HelloWorld Modelo de datos con Play JSON format en el objeto complementario como se muestra a continuación:

HolaMundo.scala

12345678 package models import play.api.libs.json.Json case class HelloWorld(module:String) object HelloWorld {    implicit val writes = Json.writes[HelloWorld] }

Descripción:

      • La clase Case está tomando un parámetro String para representar el nombre del módulo Play Framework.
      • HelloWorld objeto complementario define las siguientes escrituras de Play Framework como objeto implícito:
1 implicit val writes = Json.writes[HelloWorld]

Como se mencionó, el convertidor Writes de Play Framework se usa para convertir un valor (tipo o valor de Scala) en un valor JSON (JsValue).

    • Desarrolla hello función en HelloWorldJSONController controlador como se muestra a continuación:

HelloWorldJSONController.scala

01020304050607080910111213141516 package controllers import javax.inject.Inject import models.HelloWorld import play.api.libs.json.Json._ import play.api.mvc.InjectedController class HelloWorldJSONController @Inject () extends InjectedController {    def hello(module: String) = Action {      Ok(toJson(HelloWorld(module)))    } }

Descripción:

      • Al igual que los ejemplos anteriores, hemos desarrollado un ejemplo extendiendo InjectedController y usando @Inject anotación
      • A diferencia de los ejemplos anteriores, hello La acción o función NO utiliza ninguna plantilla de vista de Scala para responder al usuario final. Está enviando directamente HelloWorld Clase de caso como resultados de reproducción para el usuario final, como se muestra a continuación:
1 Ok(toJson(HelloWorld(module)))

Aquí Play Framework Results significa Estado OK que genera un resultado '200 OK'.

      • NO enviaremos HelloWorld Clase de caso tal como es. Primero, se está convirtiendo en un objeto JSON usando Json.toJson() como se muestra a continuación:
1 Json.toJson(HelloWorld(module))

Como se discutió en las secciones anteriores, toJson La función se utiliza para convertir un objeto Scala en un objeto JSON. Observemos la respuesta JSON en la siguiente subsección.

      • Json el objeto complementario define este toJson como se muestra a continuación:
12345 object Json { def toJson[T](t: T)(implicit obj: Writes[T]): JsValue = obj.writes(t) }

El tipo de retorno de toJson la función es JsValue. Como se mencionó, JsValue es un supertipo de todas las API Play JSON y es un tipo de valor JSON genérico.

Intentaremos desarrollar otro Endpoint para la misma funcionalidad utilizando Scala View Template pronto.

7.1 Prueba de reproducción JSON HelloWorld Ejemplo

En esta sección, probaremos el ejemplo de Play JSON HelloWorld desarrollado en la sección anterior. Realice los siguientes pasos uno por uno:

    • Para instalar y ejecutar nuestra aplicación, ejecute el siguiente comando sbt
12 $cd PlayJSONScalaHelloWorldExample $sbt run
    • Acceso http://localhost:9000/hello/json url del navegador web como se muestra a continuación y observe el resultado

Test Play JOSN + Scala HelloWorld Ejemplo con navegador

7.2 Juega JSON HelloWorld sin Json.toJson

Si observamos nuestro ejemplo anterior de Play JSON HelloWorld, nuestro HelloWorldJSONController el controlador convierte HelloWorld Objeto Scala a JsValue usando Json.toJson() utilidad y envía esa respuesta al usuario final para que la represente en un navegador web. Estaba funcionando bien.

¿Qué pasará si enviamos ese HelloWorld Scala objeto como es? Realice los siguientes cambios en nuestro controlador:

HelloWorldJSONController.scala

01020304050607080910111213141516 package controllers import javax.inject.Inject import models.HelloWorld import play.api.libs.json.Json._ import play.api.mvc.InjectedController class HelloWorldJSONController @Inject () extends InjectedController {    def hello(module: String) = Action {      Ok(HelloWorld(module))    } }

Aquí acabamos de eliminar el Json.toJson() llamada de función en hello Acción. Acceda a la misma URL http://localhost:9000/hello/json desde el navegador web como se muestra a continuación y observe los resultados:

Reproducir escenario de error de JSON + Scala HelloWorld

Aquí, si podemos observar el mensaje de error, dice claramente que necesitamos desarrollar un "Writeable[models.HelloWorld]". Discutiremos sobre Writeable en una publicación separada.

7.3 Ejemplo de Play JSON HelloWorld con vista de plantilla

Si observamos nuestro ejemplo principal de Play JSON HelloWorld, podemos decir que nuestro controlador no ha utilizado Scala View Template para representar la respuesta. Simplemente convierte nuestro modelo de datos en JSON y envía ese JSON al usuario final directamente.

En esta sección, haremos la misma funcionalidad utilizando Scala View Template. Realice los siguientes pasos para experimentar este escenario:

    • Desarrolle un nuevo punto final en el archivo de enrutamiento como se muestra a continuación:

rutas

123 ## Hello Play JSON Controller GET   /hello/:module  controllers.HelloWorldJSONController.hello(module: String) GET   /hello/view/:module  controllers.HelloWorldJSONController.helloView(module: String)

Aquí hemos añadido /hello/view/:module Punto final para asignar esta solicitud a HelloWorldJSONController.helloView() Acción.

    • Desarrolle la plantilla de vista de Scala como se muestra a continuación:

hola.scala.html

123 @(module: String) <h1>Play JSON + Scala Example</h1> <h2> @module </h2>
    • Desarrollar nueva acción helloView() en nuestro Controlador como se muestra a continuación:

HelloWorldJSONController.scala

01020304050607080910111213141516171819202122 package controllers import javax.inject.Inject import models.HelloWorld import play.api.libs.json.Json._ import play.api.mvc.InjectedController class HelloWorldJSONController @Inject () extends InjectedController {    def hello(module: String) = Action {      Ok(toJson(HelloWorld(module)))    }    def helloView(module: String) = Action {      Ok(views.html.hello(stringify(toJson(HelloWorld(module)))))    } }

Descripción:

      • Aquí hemos desarrollado una nueva Acción:helloView usando hello Plantilla de vista de Scala
      • En el primer paso, estamos convirtiendo HelloWorld modelo de datos a JSON usando Json.toJson() función
      • El tipo de retorno o anotación de tipo de Json.toJson() la función es JsValue
      • Sin embargo, nuestra plantilla de vista de saludo toma String como parámetro, por lo que debemos convertir este JsValue a cadena
1 @(module: String)
      • Estamos usando Json. stringify() función para convertir ese JsValue a String como se muestra a continuación:
12345 def helloView(module: String) = Action {    Ok(views.html.hello(Json.stringify(Json.toJson(HelloWorld(module))))) }
    • Asegúrese de que nuestro servidor esté funcionando.
    • Acceda a la misma URL http://localhost:9000/hello/view/json desde el navegador web como se muestra a continuación y observe los resultados:

Juega JSON + Scala HelloWorld con plantilla Scala

Eso es todo sobre el ejemplo básico de Play JSON + Scala HelloWorld. Exploremos algunos detalles más del módulo JSON de Play Framework con un ejemplo más en la próxima sección.

8. Reproducir ejemplo complejo JSON Scala

En la sección anterior, hemos desarrollado un ejemplo básico, simple y fácil de entender de Play JSON HelloWorld usando solo el convertidor Writes. Aquí vamos a desarrollar otro ejemplo para explorar los 3 convertidores:Lecturas, Escrituras y Formato usando Play Framework, Play JSON Module y Scala.

Vamos a utilizar la herramienta de compilación IntelliJ IDE y SBT para desarrollar esta aplicación. Si está utilizando IntelliJ IDE Ultimate Edition, primero cree una aplicación web Play Framework utilizando IDE. Si está utilizando IntelliJ IDE CE (Community Edition), descargue el proyecto Play Scala Starter desde la siguiente ubicación de GitHub de Lightbend's Play Framework Examples:
https://github.com/playframework/play-scala-starter-example

Cambié el nombre de este proyecto como "PlayJSONScalaBooksExample", lo importé a IntelliJ IDE y eliminé todos los archivos.

Luego, continúe con los siguientes pasos para desarrollar nuestra aplicación HelloWorld:

    • Los primeros dos pasos son los mismos que en nuestro ejemplo de Play JSON HelloWorld
    • Desarrolle nuestro modelo de datos de libros como se muestra a continuación:

Libro.scala

12345678 package models import play.api.libs.json.Json case class Book(isbn: String, title: String, author: String, noofpages: Int, price: Double) object Book {    implicit val format = Json.format[Book] }

Aquí estamos usando el convertidor de formato de Play Framework. Si es necesario, podemos escribir lecturas y escrituras manuales como se muestra a continuación:

Libro.scala

01020304050607080910111213141516171819202122 package models import play.api.libs.json.Json case class Book(isbn: String, title: String, author: String, noofpages: Int, price: Double) object Book {      implicit val reads: Reads[Book] = (        (JsPath \ "isbn" ).read[String] and        (JsPath \ "title" ).read[String] and        (JsPath \ "author" ).read[String] and        (JsPath \ "noofpages" ).read[Int] and        (JsPath \ "price" ).read[Double]      )(Book.apply _)    implicit val writes: Writes[Book] = (        (JsPath \ "isbn" ).write[String] and        (JsPath \ "title" ).write[String] and        (JsPath \ "author" ).write[String] and        (JsPath \ "noofpages" ).write[Int] and        (JsPath \ "price" ).write[Double]      )(unlift(Book.unapply)) }
    • Desarrolle el servicio para el modelo de dominio Book como se muestra a continuación:

BookService.scala

01020304050607080910111213141516171819202122232425262728293031 package services import models.Book class BookService {    def getBooks(): List[Book] = books    def getBook(isbn: String): Option[Book] = {      val mybook = books.filter{ book =>        book.isbn == isbn      }      mybook.headOption    }    def addBook(book: Book) = {      books :+= book      books    }    var books:List[Book] = List[Book](      Book( "ISBN01" , "Scala Reactive Programming" , "Rambabu Posa" , 550 , 35.50 ),      Book( "ISBN02" , "Scala 2.13 In Depth" , "Lokesh Posa" , 420 , 25.50 ),      Book( "ISBN03" , "Play JSON In Practice" , "Rams" , 510 , 31.50 ),      Book( "ISBN05" , "Scala In Depth" , "Rambabu Posa" , 750 , 38.90 )    ) }

Here we have hardcoded couple of Books list for out testing purpose. When we discuss about “Play Framework + Scala + Database Example”, we will try to store this data some where in Relational Database or NoSQL Data store.

    • Develop Scala View temple to display Book results as JSON output as shown below:

books.scala.html

12 @(book: String) @book
    • Develop controller for Book domain model as shown below:

BookStoreController.scala

010203040506070809101112131415161718192021222324252627282930313233 package controllers import javax.inject.Inject import models.Book import play.api.libs.json.Json._ import play.api.mvc.InjectedController import services.BookService class BookStoreController @Inject ()(bookService: BookService) extends InjectedController {    def getBooks() = Action {      val books = bookService.getBooks()      Ok(views.html.books(stringify(toJson(books))))    }    def getBook(isbn: String) = Action {      val book = bookService.getBook(isbn)      Ok(views.html.books(stringify(toJson(book))))    }    def addBook = Action(parse.json) { implicit request =>      val newBook = request.body.as[Book]      val books = bookService.addBook(newBook)      Ok(views.html.books(stringify(toJson(books))))    } }

Please observe the following two lines of code:

123 def addBook = Action(parse.json) { implicit request =>    val newBook = request.body.as[Book] }

First point, we should understand is implicit request object. To understand this, we should discuss the following two questions:

      • What does it really contain?
      • Why do we need this?

Answer to first question is that it contains User Request information like body or header. In our example, when User sent a POST request with Book information (see screenshots to understand it very well), this request implicit object’s body contains that Book information.

The Answer to the second question is that if we want to retrieve that Book information form User Request body, we should use this implicit request objeto. We can use it without implicit object also as shown below:

123 def addBook = Action(parse.json) { request =>    val newBook = request.body.as[Book] }

In our case, it works fine (test it by updating this example). However, Play Framework team (Lightbend) recommends to use this request object as implicit so that if any of User components or Play Framework components needs it as implicit, our application does NOT complain any errors.

In our example, we have retrieved our Book information using request.body.as[Book] code.

    • Define routes to Book domain model as shown below:

routes

1234 ## BookStore Play JSON Controller GET   /books/:isbn  controllers.BookStoreController.getBook(isbn: String) GET   /books        controllers.BookStoreController.getBooks() POST  /books        controllers.BookStoreController.addBook()
    • Make sure this application is up and running.
    • Please access http://localhost:9000/books url to observe the available Books list from our BookStore as shown below:

Get all Books available in BookStore

    • Please access http://localhost:9000/books url with Book details to add new Book to existing Book list of our BookStore as shown below:

Add new Book to our BookStore

    • Please access http://localhost:9000/books/ISBN04 url to observe the details of our newly added Book from our BookStore as shown below:

Get New Book Details

9. Conclusión

One of the best features of Play! Framework is that it supports REST API by design. It has a separate JSON module “play-son” to develop RESTful Web services easily. As its an independent module, we can use it not only in Play Framework, in any other web frameworks or standalone applications too.

Play JSON API defines required JSON types and some utilities to take care of supporting JSON API in Play Framework. It has 3 combinators:Reads, Writes and Format to ease the process of converting Scala Values to JsValues and vice versa.

We have developed two simple and easy to understand Play JSON examples in Scala language using SBT build tool. Please go through the Play JSON module source code to understand this API in-depth.

10. Referencias

If you are interested to learn more details about Play Framework, Play JSON, Scala Language and SBT tool, please refer the following important websites:

  • Play Framework website:https://www.playframework.com
  • Play Framework Scala API:https://www.playframework.com/documentation/2.6.x/api/scala/index.html#package
  • Play Framework Scala JSON API:https://www.playframework.com/documentation/2.6.x/ScalaJson
  • Play JSON Module source code:https://github.com/playframework/play-json
  • Scala Language:https://www.scala-lang.org
  • Scala API:https://www.scala-lang.org/api/2.12.6
  • Scala SBT tool:https://www.scala-sbt.org

11. Descarga el código fuente

That was a Play! Framework JSON &Scala Web Application Example Tutorial.json Play Framework Scala

Etiqueta Java