Tapiz Apache - Guía rápida

Apache Tapestry es un marco web de código abierto escrito en Java. Es uncomponent based web framework. Los componentes de tapiz son clases de Java. No se heredan de una clase base específica del marco ni de la implementación de una interfaz y son simplemente POJO (Objetos Java simples y antiguos).

La característica importante del Java utilizado por tapiz es Annotation. Las páginas web de Tapestry se construyen utilizando uno o más componentes, cada uno con una plantilla basada en XML y una clase de componente decorada con muchas anotaciones de Tapestry. Tapestry puede crear cualquier cosa, desde una pequeña aplicación web de una sola página hasta una masiva que consta de cientos de páginas.

Beneficios del tapiz

Algunos de los beneficios que brinda el tapiz son:

  • Aplicaciones web altamente escalables.
  • API adaptable.
  • Marco rápido y maduro.
  • Gestión de almacenamiento de estado persistente.
  • Inversión de control incorporada.

Características del tapiz

Tapiz tiene las siguientes características:

  • Recarga de clases en vivo
  • Informes de excepciones claros y detallados
  • Estructura estática, comportamientos dinámicos.
  • Uso extensivo de objetos simples de Java antiguos (POJO)
  • Codifique menos, entregue más.

¿Por qué tapiz?

Java ya tiene muchos marcos web como JSP, Struts, etc. Entonces, ¿por qué necesitamos otro marco? La mayoría de los Java Web Frameworks actuales son complejos y tienen una curva de aprendizaje empinada. Están anticuados y requieren un ciclo de compilación, prueba e implementación para cada actualización.

Por otro lado, Tapestry proporciona un enfoque moderno para la programación de aplicaciones web al proporcionar live class reloading. Mientras que otros marcos están introduciendo muchas interfaces, clases abstractas y base, Tapestry solo presenta un pequeño conjunto de anotaciones y aún brinda la capacidad de escribir aplicaciones grandes con soporte rico en AJAX.

Tapestry intenta utilizar las funciones disponibles de Java tanto como sea posible. Por ejemplo, todas las páginas de Tapestry son simplemente POJO. No impone ninguna interfaz personalizada o clase base para escribir la aplicación. En su lugar, utiliza Anotación (una opción ligera para ampliar la funcionalidad de una clase Java) para proporcionar funciones. Se basa en pruebas de batallaJava Servlet APIy se implementa como un filtro de servlet. Proporciona una nueva dimensión a la aplicación web y la programación es bastante simple, flexible, comprensible y robusta.

Flujo de trabajo

Analicemos la secuencia de acción que tiene lugar cuando se solicita una página de tapiz.

Step 1 - el Java Servletrecibe la solicitud de página. Este Servlet de Java está configurado de tal manera que la solicitud entrante se reenviará a tapiz. La configuración se realiza en elweb.xmlcomo se especifica en el siguiente programa. La etiqueta Filter and Filter Mapping redirige todas las solicitudes a Tapestry Filter .

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
   "http://java.sun.com/dtd/web-app_2_3.dtd"> 
<web-app> 
   <display-name>My Tapestry Application</display-name> 
   <context-param> 
      <param-name>tapestry.app-package</param-name> 
      <param-value>org.example.myapp</param-value> 
   </context-param> 
   <filter> 
      <filter-name>app</filter-name> 
      <filter-class>org.apache.tapestry5.TapestryFilter</filter-class> 
   </filter> 
   <filter-mapping> 
      <filter-name>app</filter-name> 
      <url-pattern>/*</url-pattern> 
   </filter-mapping> 
</web-app>

Step 2 - el Tapestry Filter llama al HttpServletRequestHandler Servicio por su Service() método.

Step 3 - HttpServletRequestHandler almacena la solicitud y la respuesta en RequestGlobals. También envuelve la solicitud y la respuesta como un objeto Solicitud y respuesta y lo envía al RequestHandler.

Step 4 - el RequestHandler es una abstracción encima de HttpServletRequestde la API de Servlet. Algunas de las características más destacadas del tapiz se realizan enRequestHandlersección. La función de tapiz se puede ampliar escribiendo un filtro en RequestHandler. RequestHandler proporciona varios filtros integrados, que incluyen:

  • CheckForUpdates Filter- Responsable de recarga de clases en vivo. Este filtro busca cambios en las clases de Java y actualiza la aplicación según sea necesario.

  • Localization Filter - Identificar la ubicación del usuario y brindar soporte de localización para la aplicación.

  • StaticFiles Filter- Identifica la solicitud estática y aborta el proceso. Una vez que se aborta el proceso, Java Servlet toma el control y procesa la solicitud.

  • Error Filter - Detecta la excepción no detectada y presenta la página del informe de excepciones.

RequestHandler también modifica y almacena la solicitud y la respuesta en RequestQlobal e invoca el servicio MasterDispatcher.

Step 5 - el MasterDispatcherse encarga de renderizar la página llamando a varios despachadores es un pedido específico. Los cuatro despachadores principales llamados por MasterDispatcher son los siguientes:

  • RootPath Dispatcher - Reconoce la ruta raíz “/” de la solicitud y la renderiza igual que la página de inicio.

  • Asset Dispatcher - Reconoció la solicitud de activos (activos de Java) al verificar el patrón de URL / activos / y envía los activos solicitados como flujos de bytes.

  • PageRender Dispatcher- La mayor parte de las operaciones de tapiz se realizan en PageRender Dispatcher y en el siguiente despachador Component Dispatcher. Este despachador reconoce la página particular de esa solicitud y su contexto de activación (información adicional). Luego procesa esa página en particular y la envía al cliente. Por ejemplo, si la URL de la solicitud es / product / 12123434, el despachador comprobará si hay alguna clase con el nombre product / 12123434 disponible. Si lo encuentra, llama a la clase product / 12123434, genera la respuesta y la envía al cliente. Si no es así, verifica la clase de producto. Si lo encuentra, llama a la clase de producto con información adicional 121234434, genera la respuesta y la envía al cliente. Esta información adicional se denomina contexto de activación. Si no se encuentra ninguna clase, simplemente reenvía la solicitud a Component Dispatcher.

  • Component Dispatcher- Component Dispatcher hace coincidir la URL de la página con el patrón - / <class_name> / <component_id>: <event_type> / <activation_context>. Por ejemplo, / product / grid: sort / asc representa la clase de producto, el componente de grid, el tipo de evento y el contexto de activación de asc. Aquí, event_type es opcional y si no se proporciona ninguno, se activará la acción de tipo de evento predeterminada. Normalmente, la respuesta del despachador de componentes es enviar una redirección al cliente. En su mayoría, la redirección coincidirá con PageRender Dispatcher en la próxima solicitud y se enviará la respuesta adecuada al cliente.

En este capítulo, discutiremos cómo instalar Tapestry en nuestra máquina.

Requisito previo

La única dependencia de Tapestry es Core Java. Tapestry se desarrolla de forma independiente sin utilizar ninguna biblioteca / marco de terceros. Incluso la biblioteca de IoC utilizada por tapiz se desarrolla desde cero. La aplicación web escrita en tapiz se puede construir e implementar desde la propia consola.

Nosotros podemos usar Maven, Eclipse y Jettypara mejorar la experiencia de desarrollo. Maven proporciona plantillas de aplicaciones de inicio rápido y opciones para alojar aplicaciones en Jetty, el servidor de desarrollo de facto de Java. Eclipse proporciona amplias funciones de gestión de proyectos y se integra bien con maven.

El desarrollo de una aplicación de tapiz ideal necesita lo siguiente:

  • Java 1.6 o posterior
  • Apache Maven
  • Eclipse IDE
  • Servidor Jetty

Verificar la instalación de Maven

Con suerte, ha instalado Maven en su máquina. Para verificar la instalación de Maven, escriba el comando que se proporciona a continuación:

mvn --version

Puede ver la respuesta como se muestra a continuación:

Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-1110T22:11:47+05:30) 
Maven home: /Users/workspace/maven/apache-maven-3.3.9 
Java version: 1.8.0_92, vendor: Oracle Corporation 
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre 
Default locale: en_US, platform encoding: UTF-8 
OS name: "mac os x", version: "10.11.4", arch: "x86_64", family: "mac"

Si Maven no está instalado, descargue e instale la última versión de maven visitando el sitio web de Maven .

Descargar tapiz

La última versión de tapiz es 5.4 y se puede descargar del sitio web de tapiz . Basta con descargar el paquete binario . Si usamos la plantilla de inicio rápido de Maven, entonces no es necesario descargar Tapestry por separado. Maven descarga automáticamente los Tapestry Jars necesarios y configura la aplicación. Discutiremos cómo crear una aplicación de tapiz básica usando Maven en el próximo capítulo.

Después de la instalación de Tapestry, creemos un nuevo proyecto inicial usando Maven como se muestra a continuación:

$ mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org

Puede ver la respuesta como se muestra a continuación:

[INFO] Scanning for projects... 
[INFO] 
[INFO] --------------------------------------------------------------------------------- 
[INFO] Building Maven Stub Project (No POM) 1 
[INFO] ---------------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) > 
generatesources @ standalone-pom >>> 
[INFO]  
[INFO] <<< maven-archetype-plugin:2.4:generate (default-cli) 
< generatesources @ standalone-pom <<< 
[INFO] 
[INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom --- 
[INFO] Generating project in Interactive mode 
[INFO] No archetype defined. Using maven-archetype-quickstart 
(org.apache.maven.archetypes:maven-archetype-quickstart:1.0)

Después de que Maven construya todas las operaciones, elija el arquetipo para crear Tapestry 5 QuickStart proyecto de la siguiente manera -

Choose archetype -

  • https://tapestry.apache.org → org.apache.tapestry: inicio rápido (Proyecto de inicio rápido de Tapestry 5)

  • https://tapestry.apache.org → org.apache.tapestry: tapestry-archetype (Tapestry 4.1.6 Arquetipo)

Elija un número o aplique un filtro (formato: [groupId:] artifactId, contiene entre mayúsculas y minúsculas):: 1

Ahora obtendrá una respuesta como la que se muestra a continuación:

Choose org.apache.tapestry:quickstart version: 
1: 5.0.19
2: 5.1.0.5 
3: 5.2.6 
4: 5.3.7 
5: 5.4.1

Extraiga el número de versión de QuickStart de la siguiente manera:

Choose a number: 5: 5

Aquí, el proyecto QuickStart toma la versión de la opción 5, "5.4.1". Ahora, el arquetipo Tapestry solicita la siguiente información una por una de la siguiente manera:

  • 5.1 groupId - Definir valor para la propiedad 'groupId':: com.example

  • 5.2 artifactId - Definir valor para la propiedad 'artifactId':: Myapp

  • 5.3 version - Definir valor para la propiedad 'versión': 1.0-SNAPSHOT::

  • 5.4 package name - Definir valor para la propiedad 'paquete': com.example:: com.example.Myapp

Ahora su pantalla le pide confirmación -

Confirmar configuración de propiedades -

  • groupId - com.example

  • artifactId - Myapp

  • version - 1.0-INSTANTÁNEA

  • package - com.example.Myapp

Verifique todas las propiedades y confirme los cambios usando la opción que se muestra a continuación:

Y: : Y

Vería una pantalla como la que se muestra a continuación.

[INFO] ---------------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: quickstart:5.4.1 
[INFO] ---------------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example 
[INFO] Parameter: artifactId, Value: Myapp 
[INFO] Parameter: version, Value: 1.0-SNAPSHOT 
[INFO] Parameter: package, Value: com.example.Myapp 
[INFO] Parameter: packageInPathFormat, Value: com/example/Myapp 
[INFO] Parameter: package, Value: com.example.Myapp 
[INFO] Parameter: version, Value: 1.0-SNAPSHOT 
[INFO] Parameter: groupId, Value: com.example 
[INFO] Parameter: artifactId, Value: Myapp 
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/java 
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/main/webapp 
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/main/resources/com/
example/Myapp 
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/resource 
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/conf 
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/site 
[INFO] project created from Archetype in dir: /Users/workspace/tapestry/Myapp 
[INFO] --------------------------------------------------------------------------------- 
[INFO] BUILD SUCCESS 
[INFO] --------------------------------------------------------------------------------- 
[INFO] Total time: 11:28 min 
[INFO] Finished at: 2016-09-14T00:47:23+05:30 
[INFO] Final Memory: 14M/142M 
[INFO] ---------------------------------------------------------------------------------

Aquí, ha creado con éxito el proyecto Tapestry Quick Start. Mover a la ubicación del recién creadoMyapp directorio con el siguiente comando y comienza a codificar.

cd Myapp

Ejecutar aplicación

Para ejecutar el proyecto de esqueleto, use el siguiente comando.

mvn jetty:run -Dtapestry.execution-mode=development

Obtienes una pantalla como esta,

[INFO] Scanning for projects... 
[INFO] 
[INFO] ---------------------------------------------------------------------------------
[INFO] Building Myapp Tapestry 5 Application 1.0-SNAPSHOT 
[INFO] ---------------------------------------------------------------------------------
........ 
........ 
........ 
Application 'app' (version 1.0-SNAPSHOT-DEV) startup time: 346 ms to build IoC 
Registry, 1,246 ms overall.  
 ______                  __             ____ 
/_  __/__ ____  ___ ___ / /_______ __  / __/ 
 / / / _ `/ _ \/ -_|_-</ __/ __/ // / /__ \  
/_/  \_,_/ .__/\__/___/\__/_/  \_, / /____/ 
        /_/                   /___/  5.4.1 (development mode)   
[INFO] Started [email protected]:8080 
[INFO] Started Jetty Server

A partir de ahora, hemos creado un proyecto básico de inicio rápido en Tapestry. Para ver la aplicación en ejecución en el navegador web, simplemente escriba la siguiente URL en la barra de direcciones y presione enter -

https://localhost:8080/myapp

Aquí, myapp es el nombre de la aplicación y el puerto predeterminado de la aplicación en modo de desarrollo es 8080.

Usando Eclipse

En el capítulo anterior, analizamos cómo crear una aplicación de inicio rápido de Tapestry en CLI. Este capítulo explica cómo crear una aplicación esqueleto enEclipse IDE.

Usemos un arquetipo de Maven para crear una aplicación esqueleto. Para configurar una nueva aplicación, puede seguir los pasos que se indican a continuación.

Paso 1: Abra el IDE de Eclipse

Abra su Eclipse y elija Archivo → Nuevo → Proyecto… → opción como se muestra en la siguiente captura de pantalla.

Ahora, elija la opción de proyecto Maven → Maven.

Note - Si Maven no está configurado, configure y cree un proyecto.

Después de seleccionar el proyecto Maven, haga clic en Siguiente y nuevamente haga clic en el botón Siguiente.

Después de eso, obtendrá una pantalla donde debe elegir la opción de configuración. Una vez configurado, aparecerá la siguiente pantalla.

Paso 2: Configuración del catálogo

Una vez realizado el primer paso, debe hacer clic en Add Remote Catalog. Luego agregue los siguientes cambios como se muestra en la siguiente captura de pantalla.

Ahora, se agrega Apache Tapestry Catalog. Luego, elija la opción de filtro org.apache.tapestry quickstart 5.4.1 como se muestra a continuación.

Luego haga clic en Siguiente y aparecerá la siguiente pantalla.

Paso 3: configurar GroupId, ArtifactId, versión y paquete

Agregue los siguientes cambios a la configuración de Tapestry Catalog.

Luego haga clic en el botón Finalizar, ahora hemos creado la primera aplicación esqueleto. La primera vez que usa Maven, la creación del proyecto puede llevar un tiempo, ya que Maven descarga muchas dependencias JAR para Maven, Jetty y Tapestry. Una vez que Maven finalice, verá un nuevo directorio, MyFirstApplication en la vista del Explorador de paquetes.

Paso 4: Ejecute la aplicación utilizando el servidor Jetty

Puede utilizar Maven para ejecutar Jetty directamente. Haga clic con el botón derecho en el proyecto MyFirstApplication en la vista del Explorador de paquetes y seleccione Ejecutar como → Compilación de Maven ... aparecerá la pantalla que se muestra a continuación.

En el cuadro de diálogo de configuración, ingrese la opción de objetivos como "embarcadero: ejecutar" y luego haga clic en el botón Ejecutar.

Una vez que se inicialice Jetty, verá la siguiente pantalla en su consola.

Paso 5: ejecutar en el navegador web

Escriba la siguiente URL para ejecutar la aplicación en un navegador web:

https://loclhost:8080/MyFirstApplication

Paso 6: Detenga el servidor Jetty

Para detener el servidor Jetty, haga clic en el icono cuadrado rojo en su consola como se muestra a continuación.

Aquí está el diseño del código fuente creado por Maven Quickstart CLI. Además, este es el diseño sugerido de una aplicación de tapiz estándar.

├── build.gradle 
├── gradle 
│   └── wrapper 
│       ├── gradle-wrapper.jar 
│       └── gradle-wrapper.properties 
├── gradlew 
├── gradlew.bat 
├── pom.xml 
├── src 
│   ├── main 
│   │   ├── java 
│   │   │   └── com 
│   │   │       └── example 
│   │   │           └── MyFirstApplication 
│   │   │               ├── components 
│   │   │               ├── data 
│   │   │               ├── entities 
│   │   │               ├── pages 
│   │   │               └── services 
│   │   ├── resources 
│   │   │   ├── com 
│   │   │   │   └── example 
│   │   │   │       └── MyFirstApplication 
│   │   │   │           ├── components 
│   │   │   │           ├── logback.xml 
│   │   │   │           └── pages 
│   │   │   │               └── Index.properties  
│   │   │   ├── hibernate.cfg.xml 
│   │   │   └── log4j.properties
│   │   └── webapp 
│   │       ├── favicon.ico 
│   │       ├── images 
│   │       │   └── tapestry.png 
│   │       ├── mybootstrap 
│   │       │   ├── css 
│   │       │   │   ├── bootstrap.css 
│   │       │   │   └── bootstrap-theme.css 
│   │       │   ├── fonts 
│                   ├── glyphicons-halflings-regular.eot 
│   │       │   │   ├── glyphicons-halflings-regular.svg 
│   │       │   │   ├── glyphicons-halflings-regular.ttf 
│   │       │   │   ├── glyphicons-halflings-regular.woff 
│   │       │   │   └── glyphicons-halflings-regular.woff2 
│   │       │   └── js 
│   │       └── WEB-INF 
│   │           ├── app.properties 
│   │           └── web.xml 
│   ├── site 
│   │   ├── apt 
│   │   │   └── index.apt 
│   │   └── site.xml 
│   └── test 
│       ├── conf 
│       │   ├── testng.xml 
│       │   └── webdefault.xml 
│       ├── java 
│       │   └── PLACEHOLDER 
│       └── resources 
│           └── PLACEHOLDER 
└── target     
   ├── classes     
   │   ├── com  
   │   │   └── example
   │   │       └── MyFirstApplication     
   │   │           ├── components     
   │   │           ├── data     
   │   │           ├── entities     
   │   │           ├── logback.xml     
   │   │           ├── pages 
   │   │           │   └── Index.properties 
   │   │           └── services     
   │   ├── hibernate.cfg.xml 
   │   └── log4j.properties     
   ├── m2e-wtp 
   │   └── web-resources 
   │       └── META-INF     
   │           ├── MANIFEST.MF 
   │           └── maven 
   │               └── com.example 
   │                   └──MyFirstApplication     
   │                     ├── pom.properties 
   │                       └── pom.xml     
   ├── test-classes 
   │   └── PLACEHOLDER 
   └── work         
      ├── jsp         
      ├── sampleapp.properties 
      └── sampleapp.script

El diseño predeterminado está organizado como el WAR Internal File Format. El uso del formato WAR ayuda a ejecutar la aplicación sin empaquetar ni implementar. Este diseño es solo una sugerencia, pero la aplicación se puede organizar en cualquier formato, si se empaqueta en un formato WAR adecuado durante la implementación.

El código fuente se puede dividir en las siguientes cuatro secciones principales.

  • Java Code - Todos los códigos fuente de Java se colocan bajo /src/main/javacarpeta. Las clases de página de tapiz se colocan en la carpeta "Páginas" y las clases de componentes de tapiz se colocan en la carpeta de componentes. Las clases de servicios de tapices se colocan en la carpeta de servicios.

  • ClassPath Resources- En Tapestry, la mayoría de las clases tienen recursos asociados (Plantilla XML, archivos JavaScript, etc.). Estos recursos se colocan bajo el/src/main/resourcescarpeta. Las clases de página de Tapestry tienen sus recursos asociados en la carpeta "Páginas" y las clases de componentes de Tapestry tienen sus recursos asociados en la carpeta de Componentes. Estos recursos están empaquetados en elWEB-INF/classes carpeta de la GUERRA.

  • Context Resources - Son recursos estáticos de una aplicación web como Imágenes, Hoja de estilo y Biblioteca JavaScript / Modules. They are usually placed under the /src/main/webapp carpeta y se llaman Context Resources. Además, el archivo de descripción de la aplicación web (de Java Servlet), web.xml se coloca debajo delWEB-INF carpeta de recursos de contexto.

  • Testing Code - Estos son archivos opcionales que se utilizan para probar la aplicación y se colocan bajo el src/test/java y src/test/Carpetas de recursos. No están empaquetados en WAR.

Apache Tapestry sigue Convention over Configurationen todos los aspectos de la programación. Cada característica del marco tiene una convención predeterminada sensible.

Por ejemplo, como aprendimos en el capítulo Diseño del proyecto, todas las páginas deben colocarse en el /src/main/java/«package_path»/pages/ carpeta para ser considerada como páginas de tapiz.

En otro sentido, no es necesario configurar una Clase Java en particular como Tapestry Pages. Basta con colocar la clase en una ubicación predefinida. En algunos casos, es extraño seguir la convención predeterminada de Tapestry.

Por ejemplo, el componente Tapestry puede tener un método setupRenderque se disparará al inicio de la fase de renderizado. Un desarrollador puede querer usar su propio nombre de opinión, digamosinitializeValue. En esta situación, Tapestry proporcionaAnnotation para anular las convenciones como se muestra en el siguiente bloque de código.

void setupRender() { 
   // initialize component 
}  
@SetupRender 
void initializeValue() { 
   // initialize component 
}

Ambas formas de programación son válidas en Tapestry. En resumen, la configuración predeterminada de Tapestry es bastante mínima. Solo elApache Tapestry Filter (Java Servlet Filter) necesita ser configurado en el “Web.xml” para el correcto funcionamiento de la aplicación.

Tapestry proporciona otra forma de configurar la aplicación y se denomina como AppModule.java.

La anotación es una característica muy importante que Tapestry aprovecha para simplificar el desarrollo de aplicaciones web. Tapestry proporciona muchas anotaciones personalizadas. Tiene anotaciones para clases, métodos y campos de miembros. Como se discutió en la sección anterior, la Anotación también se puede usar para anular la convención predeterminada de una función. Las anotaciones de tapiz se agrupan en cuatro categorías principales y son las siguientes.

Anotación de componente

Se utiliza en clases de páginas, componentes y mixins. Algunas de las anotaciones útiles son:

  • @Property- Es aplicable a campos. Se utiliza para convertir un campo en una propiedad de tapiz.

  • @Parameter- Es aplicable a campos. Se utiliza para especificar un campo como parámetro de un componente.

  • @Environmental- Es aplicable a campos. Se utiliza para compartir un campo privado entre diferentes componentes.

  • @import- Es aplicable a clases y campos. Se utiliza para incluir activos, CSS y JavaScript.

  • @Path - Se usa junto con la anotación @Inject para inyectar un activo basado en una ruta.

  • @Log- Es aplicable a clases y campos. Se utiliza con fines de depuración. Se puede utilizar para emitir información de eventos del componente como el inicio del evento, el final del evento, etc.

Anotación de IoC

Se utiliza para inyectar objetos en el contenedor de IoC. Algunas de las anotaciones útiles son:

  • @Inject- Es aplicable a campos. Se utiliza para marcar los parámetros que deben inyectarse en el contenedor de IoC. Marca los campos que deben inyectarse en los componentes.

  • @Value- Es aplicable a campos. Se usa junto con la anotación @inject para inyectar un valor literal en lugar de un servicio (que es el comportamiento predeterminado de la anotación @Inject).

Anotación para clases de retención de datos

Se utiliza para especificar información específica del componente en una clase (generalmente modelos o clases de almacenamiento de datos) para componentes de alto nivel como

  • Grid (utilizado para crear datos tabulares avanzados como informes, galerías, etc.)

  • BeanEditForm (Se usa para crear formularios avanzados)

  • Hibernate (Usado en acceso avanzado a bases de datos), etc.

Estas anotaciones se agregan y empaquetan en un frasco separado sin ninguna dependencia de tapiz. Algunas de las anotaciones son:

  • @DataType- Se utiliza para especificar el tipo de datos del campo. El componente Tapiz puede usar esta información para crear un diseño o un marcado en la capa de presentación.

  • @Validate - Se utiliza para especificar la regla de validación de un campo.

Estas separaciones permiten que la aplicación Tapestry utilice un Multi-Tier Design.

Tapestry Application es simplemente una colección de Tapestry Pages. Trabajan juntos para formar una aplicación web bien definida. Cada página tendrá una plantilla XML correspondiente y cero, uno o más componentes. La página y el componente son iguales, excepto que la página es un componente raíz y, por lo general, la crea un desarrollador de aplicaciones.

Components are children of the root Pagecomponent. Tapestry tiene muchos componentes integrados y tiene la opción de crear un componente personalizado.

Páginas

Como se mencionó anteriormente, las páginas son componentes básicos de una aplicación de tapiz. Las páginas son POJO simples, colocadas debajo de:/src/main/java/«package_path»/pages/carpeta. Cada página tendrá su correspondienteXML Template y su ubicación predeterminada es - /src/main/resources/«package_name»/pages/.

Puede ver aquí que la estructura de la ruta es similar para Página y Plantilla, excepto que la plantilla está en el Resource Folder.

Por ejemplo, una página de registro de usuario en una aplicación Tapestry con el nombre del paquete: com.example.MyFirstApplication tendrá los siguientes archivos de página y plantilla:

  • Java Class -

    /src/main/java/com/example/MyFirstApplication/pages/index.java

  • XML Template -

    /src/main/resources/com/example/MyFirstApplication/pages/index.tml

Creemos un simple Hello Worldpágina. Primero, necesitamos crear unJava Class en - /src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java ”.

package com.example.MyFirstApplication.pages; 
public class HelloWorld { 
}

Luego, cree una plantilla XML en -

“/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.html”.

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <title>Hello World Page</title> 
   </head> 
   <body> 
      <h1>Hello World</h1> 
   </body> 
</html>

Ahora, se puede acceder a esta página en https://localhost:8080/myapp/helloworld. Esta es una página de tapiz simple. Tapestry ofrece muchas más funciones para desarrollar páginas web dinámicas, que analizaremos en los siguientes capítulos.

Consideremos la plantilla XML Tapestry en esta sección. XML Template es un documento XML bien formado. La capa de presentación (interfaz de usuario) de una página es una plantilla XML. Una plantilla XML tiene marcado HTML normal además de los elementos que se indican a continuación:

  • Espacio de nombres de tapiz
  • Expansions
  • Elements
  • Components

Analicemos ahora en detalle.

Espacio de nombres de tapiz

Los espacios de nombres de tapiz no son más que espacios de nombres XML. Los espacios de nombres deben definirse en el elemento raíz de la plantilla. Se utiliza para incluir componentes de tapiz e información relacionada con los componentes en la plantilla. Los espacios de nombres más utilizados son los siguientes:

  • xmlns: t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” - Se utiliza para identificar los elementos, componentes y atributos de Tapestry.

  • xmlns: p = "tapestry: parameter": se utiliza para pasar fragmentos arbitrarios de código a los componentes.

Un ejemplo de espacio de nombres Tapestry es el siguiente:

<html xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_3.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <head> 
      <title>Hello World Page</title> 
   </head>  
   <body> 
      <h1>Hello World</h1> 
      <t:eventlink page = "Index">refresh page</t:eventlink> 
   </body> 
</html>

Expansiones

La expansión es un método simple y eficiente para cambiar dinámicamente la plantilla XML durante la fase de representación de la página. La expansión usa la sintaxis $ {<name>}. Hay muchas opciones para expresar la expansión en la plantilla XML. Veamos algunas de las opciones más utilizadas:

Expansiones de propiedad

Asigna la propiedad definida en la clase Page correspondiente. Sigue la Especificación Java Bean para la definición de propiedades en una clase Java. Va un paso más allá al ignorar los casos del nombre de la propiedad. Cambiemos el ejemplo de "Hola mundo" usando la expansión de propiedad. El siguiente bloque de código es la clase Page modificada.

package com.example.MyFirstApplication.pages; 
public class HelloWorld {   
   // Java Bean Property 
   public String getName { 
      return "World!"; 
   } 
}

Luego, cambie la plantilla XML correspondiente como se muestra a continuación.

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <title>Hello World Page</title> 
   </head> 
   <body> 
      <!-- expansion --> 
      <h1>Hello ${name}</h1> 
   </body> 
</html>

Aquí, hemos definido name como Java Bean Property en la clase Page y lo procesó dinámicamente en una plantilla XML usando expansión ${name}.

Expansión de mensajes

Cada clase de página puede tener o no un archivo de propiedad asociado: «page_name».propertiesen la carpeta de recursos. Los archivos de propiedades son archivos de texto sin formato que tienen un solo par clave / valor (mensaje) por línea. Creemos un archivo de propiedades para la página HelloWorld en -

“/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties” y agregue un mensaje de “saludo”.

Greeting = Hello

los Greeting El mensaje se puede utilizar en la plantilla XML como ${message:greeting}

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <title>Hello World Page</title> 
   </head> 
   <body> 
      <!-- expansion --> 
      <h1>${message:greeting} ${name}</h1> 
   </body> 
</html>

Elementos

Tapestry tiene un pequeño conjunto de elementos que se utilizarán en Plantillas XML. Los elementos son etiquetas predefinidas definidas en el espacio de nombres Tapestry:

https://tapestry.apache.org/schema/tapestry_5_4.xsd

Cada elemento se crea para un propósito específico. Los elementos de tapiz disponibles son los siguientes:

<t: cuerpo>

Cuando dos componentes están anidados, es posible que la plantilla del componente principal tenga que envolver la plantilla del componente secundario. El elemento <t: body> es útil en esta situación. Uno de los usos de <t: body> es en el diseño de la plantilla.

En general, la interfaz de usuario de una aplicación web tendrá un encabezado común, pie de página, menú, etc. Estos elementos comunes se definen en una plantilla XML y se denomina diseño de plantilla o componente de diseño. En Tapestry, debe ser creado por un desarrollador de aplicaciones. Un componente de diseño es solo otro componente y se coloca en la carpeta de componentes, que tiene la siguiente ruta:src/main/«java|resources»/«package_name»/components.

Creemos un componente de diseño simple llamado MyCustomLayout. El código de MyCustomLayout es el siguiente:

<!DOCTYPE html> 
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <meta charset = "UTF-8" />
      <title>${title}</title>  
   </head> 
   <body> 
      <div>Sample Web Application</div> 
      <h1>${title}</h1> 
      <t:body/> 
      
      <div>(C) 2016 TutorialsPoint.</div> 
   </body> 
</html>

package com.example.MyFirstApplication.components;  

import org.apache.tapestry5.*; 
import org.apache.tapestry5.annotations.*; 
import org.apache.tapestry5.BindingConstants;  

public class MyCustomLayout { 
   @Property 
   @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL) 
      private String title; 
}

En la clase de componente MyCustomLayout, declaramos un campo de título y, al usar la anotación, lo hemos hecho obligatorio. Ahora, cambie la plantilla HelloWorld.html para usar nuestro diseño personalizado como se muestra en el bloque de código a continuación.

<html>
   t:type = "mycustomlayout" title = "Hello World Test page"
      xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <h1>${message:greeting} ${name}</h1> 
</html>

Podemos ver aquí que la plantilla XML no tiene etiquetas de cabeza y cuerpo. Tapestry recopilará estos detalles del componente de diseño y el <t: body> del componente de diseño será reemplazado por la plantilla HelloWorld. Una vez que todo esté hecho, Tapestry emitirá un marcado similar al que se especifica a continuación:

<!DOCTYPE html> 
<html> 
   <head> 
      <meta charset = "UTF-8" /> 
      <title>Hello World Test Page</title> 
   </head> 
   <body> 
      <div>Sample Web Application</div> 
      <h1>Hello World Test Page</h1> 
      <h1>Hello World!</h1> 
      <div>(C) 2016 TutorialsPoint.</div> 
   </body> 
</html>

Los diseños se pueden anidar. Por ejemplo, podemos ampliar nuestro diseño personalizado al incluir la funcionalidad de administración y usarlo para la sección de administración como se especifica a continuación.

<html t:type = "MyCommonLayout" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   
   <div><!-- Admin related items --><div> 
   <t:body/> 
  
</html>

<t: contenedor>

<T: container> es un elemento de nivel superior e incluye un espacio de nombres tapiz. Se utiliza para especificar la sección dinámica de un componente.

Por ejemplo, un componente de cuadrícula puede necesitar una plantilla para identificar cómo representar sus filas - tr (y columna td) dentro de una tabla HTML.

<t:container xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <td>${name}</td> 
   <td>${age}</td> 
</t:container>

<t: block>

El <t: block> es un marcador de posición para una sección dinámica en la plantilla. Generalmente, el elemento de bloque no se procesa. Solo los componentes definidos en la plantilla utilizan elementos de bloque. Los componentes inyectarán datos dinámicamente en el elemento de bloque y los renderizarán. Uno de los casos de uso más populares esAJAX.

El elemento de bloque proporciona la posición exacta y el marcado para que se rendericen los datos dinámicos. Cada elemento de bloque debe tener una propiedad Java correspondiente. Solo entonces se puede renderizar dinámicamente. La identificación del elemento de bloque debe seguir las reglas de identificación de variables de Java. La muestra parcial se proporciona a continuación.

@Inject 
private Block block;  
<html t:type = "mycustomlayout" title = "block example" 
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
<h1>${title}</h1>  
<!--  
   ... 
   ...  
--> 
<t:block t:id = "block"> 
   <h2>Highly dynamic section</h2> 
   I'v been updated through AJAX call 
   The current time is: <strong>${currentTime}</strong>
</t:block>  
<!--  
   ... 
   ...  
-->  
</html>

<t: contenido>

El elemento <t: content> se utiliza para especificar el contenido real de la plantilla. En general, todo el marcado se considera parte de la plantilla. Si se especifica <t: content>, solo se considerará el marcado dentro de él. Los diseñadores utilizan esta función para diseñar una página sin un componente de diseño.

<t: eliminar>

<T: remove> es todo lo contrario al elemento de contenido. El marcado dentro del elemento de eliminación no se considera parte de la plantilla. Se puede utilizar solo para comentarios del servidor y para fines de diseño.

Bienes

Los activos son archivos de recursos estáticos, como hojas de estilo, imágenes y archivos JavaScript. Generalmente, los activos se colocan en el directorio raíz de la aplicación web./src/main/webapp.

<head> 
   <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

Tapestry también trata los archivos almacenados en el Java Classpathcomo Activo. Tapestry ofrece opciones avanzadas para incluir Activos en la plantilla mediante la opción de expansión.

  • Context - Opción para obtener activos disponibles en contexto web.

<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>

asset- Los componentes suelen almacenar sus propios activos dentro del archivo jar junto con las clases de Java. A partir de Tapestry 5.4, la ruta estándar para almacenar activos en classpath esMETA-INF/assets. Para las bibliotecas, la ruta estándar para almacenar activos esMETA-INF/assets/«library_name»/. asset: también puede llamar context: expansión para obtener activos del contexto web.

<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>

Los activos se pueden inyectar en la página de tapiz o en el componente mediante la anotación de inyección y ruta. El parámetro para la anotación de ruta es la ruta relativa de los activos.

@Inject 
@Path("images/edit.png") 
private Asset icon;

los Path parameter también puede contener símbolos de tapiz definidos en el AppModule.java sección.

Por ejemplo, podemos definir un símbolo, skin.root con el valor context: skins / basic y usarlo como se muestra a continuación:

@Inject 
@Path("${skin.root}/style.css") 
private Asset style;

Localización

La inclusión de recursos a través de tapices proporciona una funcionalidad adicional. Una de esas funciones es la "localización". Tapestry verificará la configuración regional actual e incluirá los recursos adecuados.

Por ejemplo, si la configuración regional actual se establece como de, luego edit_de.png se incluirá en lugar de edit.png.

CSS

Tapestry tiene soporte para hojas de estilo incorporado. El tapiz se inyectarátapestry.csscomo parte de la pila principal de Javascript. De Tapestry 5.4, tapiz incluyebootstrap css frameworktambién. Podemos incluir nuestra propia hoja de estilo usando una etiqueta de enlace normal. En este caso, las hojas de estilo deben estar en el directorio raíz de la web:/src/main/webapp/.

<head> 
   <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

Tapestry proporciona opciones avanzadas para incluir hojas de estilo en la plantilla a través de la opción de expansión como se discutió anteriormente.

<head> 
   <link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>

Tapestry también proporciona anotaciones de importación para incluir hojas de estilo directamente en las clases de Java.

@Import(stylesheet="context:css/site.css") 
public class MyCommonLayout { 
}

Tapestry proporciona muchas opciones para administrar la hoja de estilo a través de AppModule.java. Algunas de las opciones importantes son:

  • Es posible que se elimine la hoja de estilo predeterminada del tapiz.

@Contribute(MarkupRenderer.class) 

public static void 
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) { 
   configuration.override("InjectDefaultStyleheet", null); 
}
  • Bootstrap también se puede desactivar anulando su ruta.

configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
  • Habilite la minimización dinámica de los activos (CSS y JavaScript). Necesitamos incluirtapestry-webresources dependencia (en pom.xml) también.

@Contribute(SymbolProvider.class) 
@ApplicationDefaults 

public static void contributeApplicationDefaults( 
   MappedConfiguration<String, String> configuration) { 
   
   configuration.add(SymbolConstants.MINIFICATION_ENABLED, "true"); 
} 

<dependency> 
   <groupId>org.apache.tapestry</groupId> 
   <artifactId>tapestry-webresources</artifactId> 
   <version>5.4</version> 
</dependency>

JavaScript del lado del cliente

La generación actual de aplicaciones web depende en gran medida de JavaScript para proporcionar una rica experiencia del lado del cliente. Tapestry lo reconoce y proporciona soporte de primera clase para JavaScript. El soporte de JavaScript está profundamente arraigado en el tapiz y está disponible en cada fase de la programación.

Anteriormente, Tapestry solía admitir solo Prototype y Scriptaculous. Pero, a partir de la versión 5.4, tapestry reescribió completamente la capa de JavaScript para hacerla lo más genérica posible y proporcionar soporte de primera clase para JQuery, la biblioteca de facto para JavaScript. Además, tapestry fomenta la programación de JavaScript basada en módulos y admite RequireJS, una popular implementación del lado del cliente de AMD (Definición de módulo asincrónico: especificación de JavaScript para admitir módulos y su dependencia de manera asincrónica).

Ubicación

Los archivos JavaScript son activos de la aplicación Tapestry. De acuerdo con las reglas de activos, los archivos JavaScript se colocan en contexto web,/sr/main/webapp/ o colocado dentro del frasco debajo META-INF/assets/ location.

Vinculación de archivos JavaScript

La forma más sencilla de vincular archivos JavaScript en la plantilla XML es utilizando directamente la etiqueta de secuencia de comandos, que es: <script language = "javascript" src = "relative/path/to/js"></script>. Pero tapiz no recomienda estos enfoques. Tapestry ofrece varias opciones para vincular archivos JavaScript directamente en la propia página / componente. Algunos de estos se dan a continuación.

  • @import annotation- La anotación @import proporciona la opción de vincular varias bibliotecas de JavaScript mediante la expresión de contexto. Se puede aplicar tanto a la clase Page como a su método. Si se aplica a una clase Page, se aplica a todos sus métodos. Si se aplica al método de una página, solo se aplica a ese método y luego Tapestry vincula la biblioteca de JavaScript solo cuando se invoca el método.

@Import(library = {"context:js/jquery.js","context:js/myeffects.js"}) 

public class MyComponent { 
   // ... 
}
  • JavaScriptSupport interface - JavaScriptSupport es una interfaz definida por tapiz y tiene un método, importJavaScriptLibrarypara importar archivos JavaScript. El objeto JavScriptSupport se puede crear fácilmente simplemente declarando y anotando con la anotación @Environmental.

@Inject @Path("context:/js/myeffects.js") 
private Asset myEffects;  

@Environmental 
private JavaScriptSupport javaScriptSupport;  
void setupRender() { 
   javaScriptSupport.importJavaScriptLibrary(myEffects); 
}
  • JavaScripSupport solo se puede inyectar en un componente utilizando el @Environmentalanotación. Para los servicios, necesitamos utilizar un@Inject anotación o agregarlo como un argumento en el método constructor del servicio.

@Inject 
private JavaScriptSupport javaScriptSupport; 
public MyServiceImpl(JavaScriptSupport support) { 
   // ... 
}
  • addScript method - Es similar a la interfaz de JavaScriptSupport, excepto que utiliza el addScript y el código se agrega directamente a la salida en la parte inferior de la página.

void afterRender() { 
   javaScriptSupport.addScript(
      "$('%s').observe('click', hideMe());", container.getClientId()); 
}

Pila de JavaScript

Tapestry permite combinar y utilizar un grupo de archivos JavaScript y hojas de estilo relacionadas como una sola entidad. Actualmente, Tapestry incluye pilas basadas en Prototype y JQuery.

Un desarrollador puede desarrollar sus propias pilas implementando el JavaScriptStack interfaz y registrarlo en el AppModule.java. Una vez registrado, la pila se puede importar utilizando el@import anotación.

@Contribute(JavaScriptStackSource.class) 
public static void addMyStack(
   MappedConfiguration<String, JavaScriptStack> configuration) { 
   
   configuration.addInstance("MyStack", myStack.class); 
}  

@Import(stack = "MyStack") 
public class myPage { 
}

Como se mencionó anteriormente, los componentes y las páginas son iguales, excepto que la página es el componente raíz e incluye uno o más componentes secundarios. Los componentes siempre residen dentro de una página y hacen casi toda la funcionalidad dinámica de la página.

Los componentes de tapiz representan enlaces HTML simples a la funcionalidad de cuadrícula compleja con interactive AJAX. Un componente también puede incluir otro componente. Los componentes del tapiz constan de los siguientes elementos:

  • Component Class - La clase principal de Java del componente.

  • XML Template- La plantilla XML es similar a la plantilla de página. La clase de componente representa la plantilla como resultado final. Es posible que algunos componentes no tengan plantillas. En este caso, la salida será generada por la propia clase de componente usando elMarkupWriter clase.

  • Body- El componente especificado dentro de la plantilla de página puede tener un marcado personalizado y se denomina "Cuerpo del componente". Si la plantilla de componente tiene<body />, entonces el elemento <body /> será reemplazado por el cuerpo del componente. Esto es similar al diseño que se discutió anteriormente en la sección de plantillas XML.

  • Rendering - La representación es un proceso que transforma la plantilla XML y el cuerpo del componente en una salida real del componente.

  • Parameters - Se utiliza para crear comunicación entre componentes y páginas y, por lo tanto, pasar datos entre ellos.

  • Events- Delega la funcionalidad de los componentes a su contenedor / padre (páginas u otro componente). Se utiliza ampliamente en la navegación de páginas.

Representación

La renderización de un componente se realiza en una serie de fases predefinidas. Cada fase del sistema de componentes debe tener un método correspondiente definido por convención o anotación en la clase de componente.

// Using annotaion 
@SetupRender 
void initializeValues() { 
   // initialize values 
}

// using convention 
boolean afterRender() { 
   // do logic 
   return true; 
}

Las fases, su nombre de método y sus anotaciones se enumeran a continuación.

Anotación Nombres de métodos predeterminados
@SetupRender setupRender ()
@BeginRender beginRender ()
@BeforeRenderTemplate beforeRenderTemplate ()
@BeforeRenderBody beforeRenderBody ()
@AfterRenderBody afterRenderBody ()
@DespuésRenderTemplate afterRenderTemplate ()
@AfterRender afterRender ()
@CleanupRender cleanupRender ()

Cada fase tiene un propósito específico y son los siguientes:

SetupRender

SetupRender inicia el proceso de renderizado. Suele configurar los parámetros del componente.

BeginRender

BeginRender comienza a renderizar el componente. Por lo general, muestra la etiqueta de inicio / inicio del componente.

BeforeRenderTemplate

BeforeRenderTemplate se usa para decorar la plantilla XML, agregando un marcado especial alrededor de la plantilla. También proporciona una opción para omitir la representación de la plantilla.

BeforeRenderBody

BeforeRenderTemplate proporciona una opción para omitir la representación del elemento del cuerpo del componente.

AfterRenderBody

AfterRenderBody se llamará después de que se renderice el cuerpo del componente.

AfterRenderTemplate

AfterRenderTemplate se llamará después de que se procese la plantilla del componente.

AfterRender

AfterRender es la contraparte de BeginRender y normalmente muestra la etiqueta de cierre.

CleanupRender

CleanupRender es la contraparte de SetupRender. Libera / elimina todos los objetos creados durante el proceso de renderizado.

El flujo de las fases de renderizado no es solo hacia adelante. Va de un lado a otro entre fases en función del valor de retorno de una fase.

Por ejemplo, si el método SetupRender devuelve falso, la renderización salta a la fase CleanupRender y viceversa. Para encontrar una comprensión clara del flujo entre las diferentes fases, verifique el flujo en el diagrama que se muestra a continuación.

Componente simple

Creemos un componente simple, Hello, que tendrá el mensaje de salida como "Hello, Tapestry". A continuación se muestra el código del componente Hello y su plantilla.

package com.example.MyFirstApplication.components;  
public class Hello {  
}
<html  
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
  
   <div> 
      <p>Hello, Tapestry (from component).</p> 
   </div> 
  
</html>

El componente Hello se puede llamar en una plantilla de página como:

<html title = "Hello component test page" 
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
<t:hello />  
</html>

De manera similar, el componente puede generar la misma salida usando MarkupWriter en lugar de la plantilla como se muestra a continuación.

package com.example.MyFirstApplication.components; 
  
import org.apache.tapestry5.MarkupWriter; 
import org.apache.tapestry5.annotations.BeginRender;   

public class Hello { 
   @BeginRender 
   void renderMessage(MarkupWriter writer) { 
      writer.write("<p>Hello, Tapestry (from component)</p>"); 
   } 
}

Cambiemos la plantilla del componente e incluyamos el elemento <body /> como se muestra en el bloque de código a continuación.

<html>  
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <div> 
      <t:body /> 
   </div> 
</html>

Ahora, la plantilla de página puede incluir el cuerpo en el marcado del componente como se muestra a continuación.

<html title = "Hello component test page" 
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <t:hello> 
      <p>Hello, Tapestry (from page).</p> 
   </t:hello> 
</html>

La salida será la siguiente:

<html> 
   <div> 
      <p>Hello, Tapestry (from page).</p> 
   </div> 
</html>

Parámetros

El propósito principal de estos parámetros es crear una conexión entre un campo del componente y una propiedad / recurso de la página. Usando parámetros, el componente y su página correspondiente se comunican y transfieren datos entre sí. Se llamaTwo Way Data Binding.

Por ejemplo, un componente de cuadro de texto utilizado para representar la edad en una página de administración de usuarios obtiene su valor inicial (disponible en la base de datos) a través del parámetro. Nuevamente, después de que la edad del usuario se actualice y se envíe de vuelta, el componente enviará la edad actualizada a través del mismo parámetro.

Para crear un nuevo parámetro en la clase de componente, declare un campo y especifique un @Parameteranotación. Este @Parameter tiene dos argumentos opcionales, que son:

  • required- hace que el parámetro sea obligatorio. Tapestry genera una excepción si no se proporciona.

  • value : Especifica el valor predeterminado del parámetro.

El parámetro debe especificarse en la plantilla de página como atributos de la etiqueta del componente. El valor de los atributos debe especificarse mediante Binding Expression / Expansion, que discutimos en los capítulos anteriores. Algunas de las expansiones que aprendimos anteriormente son:

  • Property expansion (prop:«val») - Obtener los datos de la propiedad de la clase de página.

  • Message expansion (message:«val») - Obtener los datos de la clave definida en el archivo index.properties.

  • Context expansion (context:«val») - Obtenga los datos de la carpeta de contexto web / src / main / webapp.

  • Asset expansion (asset:«val») - Obtenga los datos de los recursos incrustados en el archivo jar, / META-INF / assets.

  • Symbol expansion (symbol:«val») - Obtenga los datos de los símbolos definidos en AppModule.javafile.

Tapestry tiene muchas más expansiones útiles, algunas de las cuales se detallan a continuación:

  • Literal expansion (literal:«val») - Una cadena literal.

  • Var expansion (var:«val») - Permitir leer o actualizar una variable de renderizado del componente.

  • Validate expansion (validate:«val»)- Una cadena especializada que se usa para especificar la regla de validación de un objeto. Por ejemplo, validate: required, minLength = 5.

  • Translate (translate:«val») - Se utiliza para especificar la clase de traductor (conversión del lado del cliente a la representación del lado del servidor) en la validación de entrada.

  • Block (block:«val») - La identificación del elemento de bloque dentro de la plantilla.

  • Component (component:«val») - La identificación del otro componente dentro de la plantilla.

Todas las expansiones anteriores son de solo lectura, excepto la expansión Propiedad y la expansión Var. El componente los utiliza para intercambiar datos con la página. Cuando se utiliza la expansión como valores de atributo,${...}No debería ser usado. En su lugar, utilice la expansión sin símbolos de dólar y llaves.

Componente con parámetro

Creemos un nuevo componente, HelloWithParameter modificando el componente Hello para representar dinámicamente el mensaje agregando un name en la clase de componente y cambiar la plantilla de componente y la plantilla de página en consecuencia.

  • Crea una nueva clase de componente HelloWithParameter.java.

  • Agregue un campo privado y asígnele el nombre @Parameteranotación. Utilice el argumento requerido para que sea obligatorio.

@Parameter(required = true) 
private String name;
  • Agregue un campo privado, resultado con @Properyanotación. La propiedad de resultado se utilizará en la plantilla del componente. La plantilla de componente no tiene acceso a los campos anotados con@Parameter y solo puede acceder a los campos anotados con @Property. Las variables disponibles en las plantillas de componentes se denominan Variables de renderizado.

@Property 
 private String result;
  • Agregue un método RenderBody y copie el valor del parámetro de nombre a la propiedad de resultado.

@BeginRender 
void initializeValues() { 
   result = name; 
}
  • Agregar una nueva plantilla de componente HelloWithParamter.tml y use la propiedad de resultado para representar el mensaje.

<div> Hello, ${result} </div>
  • Agregue una nueva propiedad, Nombre de usuario en la página de prueba (testhello.java).

public String getUsername() { 
   return "User1"; 
}
  • Utilice el componente recién creado en la plantilla de página y establezca la propiedad Nombre de usuario en el parámetro de nombre de HelloWithParameter componente.

<t:helloWithParameter name = "username" />

La lista completa es la siguiente:

package com.example.MyFirstApplication.components;  

import org.apache.tapestry5.annotations.*;  
public class HelloWithParameter { 
   @Parameter(required = true) 
   private String name; 
     
   @Property 
   private String result; 
   
   @BeginRender 
   void initializeValues() { 
      result = name; 
   } 
}
<html  
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <div> Hello, ${result} </div> 
  
</html>
package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.*;  
public class TestHello { 
   public String getUsername() { 
      return "User1"; 
   } 
}
<html title = "Hello component test page" 
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   <t:helloWithParameter name = "username" />
   
</html>

El resultado será el siguiente:

<div> Hello, User1 </div>

Parámetro avanzado

En los capítulos anteriores, analizamos cómo crear y usar un parámetro simple en un componente personalizado. Un parámetro avanzado también puede contener un marcado completo. En este caso, el marcado debe especificarse dentro de la etiqueta del componente, como la subsección en la plantilla de página. El componente if incorporado tiene marcado tanto para condiciones de éxito como de falla. El marcado de éxito se especifica como el cuerpo de la etiqueta del componente y el marcado de error se especifica mediante unelseparameter.

Veamos cómo usar el ifcomponente. El componente if tiene dos parámetros:

  • test - Parámetro simple basado en propiedades.

  • Else - Parámetro avanzado utilizado para especificar un marcado alternativo, si la condición falla

Tapestry verificará el valor de la propiedad de prueba usando la siguiente lógica y devolverá verdadero o falso. Se llamaType Coercion, una forma de convertir un objeto de un tipo en otro tipo con el mismo contenido.

  • Si el tipo de datos es String, "Verdadero" si no está en blanco y no es la cadena literal "Falso" (no distingue entre mayúsculas y minúsculas).

  • Si el tipo de datos es Number, Verdadero si no es cero.

  • Si el tipo de datos es Collection, Verdadero si no está vacío.

  • Si el tipo de datos es Object, Verdadero (siempre que no sea nulo).

Si la condición pasa, el componente renderiza su cuerpo; de lo contrario, representa el cuerpo del parámetro else.

La lista completa es la siguiente:

package com.example.MyFirstApplication.pages; 
public class TestIf { 
   public String getUser() { 
      return "User1"; 
   } 
}

<html title = "If Test Page" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   
   <body> 
      <h1>Welcome!</h1>  
      <t:if test = "user"> 
         Welcome back, ${user} 
         <p:else>
            Please <t:pagelink page = "login">Login</t:pagelink>  
         </p:else> 
      </t:if>
   </body>
   
</html>

Eventos de componentes / navegación de página

La aplicación de tapiz es una collection of Pagesinteractuando entre sí. Hasta ahora, hemos aprendido a crear páginas individuales sin ninguna comunicación entre ellas. El propósito principal de un evento de componente es proporcionar interacción entre páginas (también dentro de las páginas) utilizando eventos del lado del servidor. La mayoría de los eventos componentes se originan en eventos del lado del cliente.

Por ejemplo, cuando un usuario hace clic en un enlace en una página, Tapestry llamará a la misma página con la información de destino en lugar de llamar a la página de destino y generará un evento en el servidor. La página de tapiz capturará el evento, procesará la información del objetivo y hará una redirección del lado del servidor a la página de destino.

Tapiz sigue un Post/Redirect/Get (RPG) design patternpara navegar por la página. En RPG, cuando un usuario realiza una solicitud de publicación al enviar un formulario, el servidor procesará los datos publicados, pero no devolverá la respuesta directamente. En su lugar, hará una redirección del lado del cliente a otra página, que generará el resultado. Se utiliza un patrón de RPG para evitar envíos de formularios duplicados a través del botón de retroceso del navegador, el botón de actualización del navegador, etc. Tapestry proporciona un patrón de RPG al proporcionar los siguientes dos tipos de solicitud.

  • Component Event Request- Este tipo de solicitud se dirige a un componente en particular en una página y genera eventos dentro del componente. Esta solicitud solo realiza una redirección y no genera la respuesta.

  • Render Request - Estos tipos de solicitudes se dirigen a una página y transmiten la respuesta al cliente.

Para comprender los eventos del componente y la navegación de la página, necesitamos conocer el patrón de URL de la solicitud de tapiz. El patrón de URL para ambos tipos de solicitud es el siguiente:

  • Component Event Requests -

/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
  • Render Request -

/<<page_name_with_path>>/<<context_information>>

Algunos de los ejemplos de patrones de URL son:

  • La página de índice puede ser solicitada por https://«domain»/«app»/index.

  • Si la página de índice está disponible en una subcarpeta admin, entonces puede ser solicitada por https://«domain»/«app»/admin/index.

  • Si el usuario hace clic en el ActionLink component con id test en la página de índice, entonces la URL será https://«domain»/«app»/index.test.

Eventos

Por defecto, Tapestry sube OnPassivate y OnActivateeventos para todas las solicitudes. Para el tipo de solicitud de evento de componente, tapestry genera uno o más eventos adicionales según el componente. El componente ActionLink genera un evento Action, mientras que un componente Form genera múltiples eventos comoValidate, Success, etc.,

Los eventos se pueden manejar en la clase de página usando el manejador de método correspondiente. El controlador de métodos se crea mediante una convención de nomenclatura de métodos o mediante la@OnEventanotación. El formato de la convención de nomenclatura de métodos esOn«EventName»From«ComponentId».

Un evento de acción del componente ActionLink con id test se puede manejar mediante uno de los siguientes métodos:

void OnActionFromTest() { 
}  
@OnEvent(component = "test", name = "action") 
void CustomFunctionName() { 
}

Si el nombre del método no tiene ningún componente en particular, entonces se llamará al método para todos los componentes con eventos coincidentes.

void OnAction() { 
}

Evento OnPassivate y OnActivate

OnPassivate se utiliza para proporcionar información de contexto para un controlador de eventos OnActivate. En general, Tapestry proporciona la información de contexto y se puede utilizar como argumento en el controlador OnActivateevent.

Por ejemplo, si la información de contexto es 3 de tipo int, entonces el evento OnActivate se puede llamar como -

void OnActivate(int id) { 
}

En algún escenario, es posible que la información de contexto no esté disponible. En esta situación, podemos proporcionar la información de contexto al controlador de eventos OnActivate a través del controlador de eventos OnPassivate. El tipo de retorno del controlador de eventos OnPassivate debe usarse como argumento del controlador de eventos OnActivate.

int OnPassivate() { 
   int id = 3; 
   return id; 
} 
void OnActivate(int id) { 
}

Valores de retorno del controlador de eventos

Tapestry emite la redirección de páginas en función de los valores de retorno del controlador de eventos. El controlador de eventos debe devolver cualquiera de los siguientes valores.

  • Null Response- Devuelve un valor nulo. Tapestry construirá la URL de la página actual y la enviará al cliente como redireccionamiento.

public Object onAction() { 
   return null; 
}
  • String Response- Devuelve el valor de la cadena. Tapestry construirá la URL de la página que coincida con el valor y la enviará al cliente como redireccionamiento.

public String onAction() { 
   return "Index"; 
}
  • Class Response- Devuelve una clase de página. Tapestry construirá la URL de la clase de página devuelta y la enviará al cliente como redireccionamiento.

public Object onAction() { 
   return Index.class 
}
  • Page Response- Devuelve un campo anotado con @InjectPage. Tapestry construirá la URL de la página inyectada y la enviará al cliente como redireccionamiento.

@InjectPage 
private Index index;  

public Object onAction(){ 
   return index; 
}
  • HttpError- Devuelve el objeto HTTPError. Tapestry emitirá un error HTTP del lado del cliente.

public Object onAction(){ 
   return new HttpError(302, "The Error message); 
}
  • Link Response- Devuelve una instancia de enlace directamente. Tapestry construirá la URL a partir del objeto Link y la enviará al cliente como redireccionamiento.

  • Stream Response - Devuelve el StreamResponseobjeto. Tapestry enviará la transmisión como respuesta directamente al navegador del cliente. Se utiliza para generar informes e imágenes directamente y enviarlo al cliente.

  • Url Response - Devuelve el java.net.URLobjeto. Tapestry obtendrá la URL correspondiente del objeto y la enviará al cliente como redireccionamiento.

  • Object Response- Devuelve cualquier valor distinto de los valores especificados anteriormente. Tapiz generará un error.

Contexto del evento

En general, el controlador de eventos puede obtener la información de contexto mediante argumentos. Por ejemplo, si la información de contexto es 3 de tipo int, entonces el controlador de eventos será:

Object onActionFromTest(int id) {  
}

Tapestry maneja correctamente la información de contexto y la proporciona a los métodos a través de argumentos. A veces, es posible que Tapestry no pueda manejarlo correctamente debido a la complejidad de la programación. En ese momento, podemos obtener la información de contexto completa y procesarla nosotros mismos.

Object onActionFromEdit(EventContext context) { 
   if (context.getCount() > 0) { 
      this.selectedId = context.get(0); 
   } else { 
      alertManager.warn("Please select a document."); 
      return null; 
   } 
}

Este capítulo explica los componentes integrados que Tapestry tiene con ejemplos adecuados. Tapestry admite más de 65 componentes integrados. También puede crear componentes personalizados. Cubramos algunos de los componentes notables en detalle.

Si componente

El componente if se utiliza para representar un bloque de forma condicional. La condición se verifica mediante un parámetro de prueba.

Crear una pagina IfSample.java como se muestra a continuación -

package com.example.MyFirstApplication.pages;  

public class Ifsample {
   public String getUser() { 
      return "user1"; 
   } 
}

Ahora, cree un archivo de plantilla correspondiente de la siguiente manera:

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
     
   <h3>If-else component example </h3> 
   <t:if test = "user"> 
      Hello ${user} 
      <p:else>
         <h4> You are not a Tapestry user </h4> 
      </p:else> 
   </t:if> 
</html>

Solicitar la página mostrará el resultado como se muestra a continuación.

Result - http: // localhost: 8080 / MyFirstApplication / ifsample

A menos que y componente delegado

los unless componentes todo lo contrario del componente if que se discutió anteriormente. Mientras que ladelegate componentno realiza ninguna representación por sí solo. En cambio, normalmente delega el marcado al elemento de bloque. A menos que y si los componentes pueden usar delegar y bloquear para intercambiar condicionalmente el contenido dinámico.

Crear una pagina Unless.java como sigue.

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.Block; 
import org.apache.tapestry5.annotations.Property; 
import org.apache.tapestry5.ioc.annotations.Inject; 
import org.apache.tapestry5.PersistenceConstants; 
import org.apache.tapestry5.annotations.Persist;  

public class Unless { 
   @Property 
   @Persist(PersistenceConstants.FLASH) 
   private String value;  
   @Property 
   private Boolean bool; 
   @Inject 
   Block t, f, n;  
   
   public Block getCase() { 
      if (bool == Boolean.TRUE ) { 
         return t; 
      } else { 
         return f; 
      } 
   }   
}

Ahora, cree un archivo de plantilla correspondiente de la siguiente manera:

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
  
   <h4> Delegate component </h4> 
   <div class = "div1"> 
      <t:delegate to = "case"/> 
   </div> 
   <h4> If-Unless component </h4>  
   
   <div class = "div1"> 
      <t:if test = "bool"> 
         <t:delegate to = "block:t"/> 
      </t:if> 
      <t:unless test = "bool"> 
         <t:delegate to = "block:notT"/> 
      </t:unless> 
   </div>  
   
   <t:block id = "t"> 
      bool == Boolean.TRUE. 
   </t:block> 
   
   <t:block id = "notT"> 
      bool = Boolean.FALSE. 
   </t:block> 
   
   <t:block id = "f"> 
      bool == Boolean.FALSE. 
   </t:block> 
</html>

Solicitar la página mostrará el resultado como se muestra a continuación.

Result - http: // localhost: 8080 / MyFirstApplication / a menos que

Componente de bucle

El componente de bucle es el componente básico para recorrer los elementos de una colección y representar el cuerpo para cada valor / iteración.

Cree una página de bucle como se muestra a continuación:

Loop.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property;  
public class Loop { 
   @Property 
   private int i; 
}

Luego, crea la plantilla correspondiente Loop.tml

Loop.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   
   <p>This is sample parameter rendering example...</p> 
   <ol>
      <li t:type = "loop" source = "1..5" value = "var:i">${var:i}</li> 
   </ol> 
</html>

El componente de bucle tiene los siguientes dos parámetros:

  • source- Fuente de colección. 1… 5 es una expansión de propiedad que se utiliza para crear una matriz con un rango específico.

  • var- Variable de renderizado. Se utiliza para representar el valor actual en el cuerpo de la plantilla.

Solicitar la página mostrará el resultado como se muestra a continuación:

Componente PageLink

Un componente PageLink se utiliza para vincular una página de una página a otra. Cree una página de prueba de PageLink como se muestra a continuación:PageLink.java.

package com.example.MyFirstApplication.pages;  
   public class PageLink { 
}

Luego, cree un archivo de plantilla correspondiente como se muestra a continuación:

PageLink.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   
   <body> 
      <h3><u>Page Link</u> </h3> 
      <div class = "page"> 
         <t:pagelink page = "Index">Click here to navigate Index page</t:pagelink>
         <br/> 
      </div> 
   </body> 
   
</html>

El componente PageLink tiene un parámetro de página que debe hacer referencia a la página del tapiz de destino.

Result - http: // localhost: 8080 / myFirstApplication / pagelink

Componente EventLink

El componente EventLink envía el nombre del evento y el parámetro correspondiente a través de la URL. Cree una clase de página EventsLink como se muestra a continuación.

EventsLink.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property;  
public class EventsLink { 
   @Property 
   private int x; 
   void onActivate(int count) { 
      this.x = x; 
   } 
   int onPassivate() { 
      return x; 
   } 
   void onAdd(int value) { 
      x += value; 
   }   
}

Luego, cree un archivo de plantilla "EventsLink" correspondiente de la siguiente manera:

EventsLink.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <h3> Event link example </h3> 
   AddedCount = ${x}. <br/> 
   <t:eventlink t:event = "add" t:context = "literal:1">
      Click here to add count
   </t:eventlink><br/>  
</html>

EventLink tiene los siguientes dos parámetros:

  • Event- El nombre del evento que se activará en el componente EventLink. De forma predeterminada, apunta a la identificación del componente.

  • Context- Es un parámetro opcional. Define el contexto del enlace.

Result - http: // localhost: 8080 / myFirstApplication / EventsLink

Después de hacer clic en el valor de recuento, la página mostrará el nombre del evento en la URL como se muestra en la siguiente captura de pantalla de salida.

Componente ActionLink

El componente ActionLink es similar al componente EventLink, pero solo envía el ID del componente de destino. El nombre del evento predeterminado es acción.

Cree una página "ActivationLinks.java" como se muestra a continuación,

ActivationLinks.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property;  
public class ActivationLinks {  
   @Property 
   private int x;  
   void onActivate(int count) { 
      this.x = x; 
   }  
   int onPassivate() { 
      return x; 
   } 
   void onActionFromsub(int value) { 
      x -= value; 
   } 
}

Ahora, cree un archivo de plantilla correspondiente como se muestra a continuación:

ActivationLinks.tml

<html t:type = "Newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   
   <div class = "div1"> 
      Count = ${count}. <br/> 
      <t:actionlink t:id = "sub" t:context = "literal:1">
         Decrement
      </t:actionlink><br/> 
   </div> 
   
</html>

Aquí el OnActionFromSub se llamará al método al hacer clic en el componente ActionLink.

Result - http: // localhost: 8080 / myFirstApplication / ActivationsLink

Componente de alerta

Un cuadro de diálogo de alerta se utiliza principalmente para dar un mensaje de advertencia a los usuarios. Por ejemplo, si el campo de entrada requiere algún texto obligatorio pero el usuario no proporciona ninguna entrada, entonces, como parte de la validación, puede usar un cuadro de alerta para dar un mensaje de advertencia.

Cree una página de "Alertas" como se muestra en el siguiente programa.

Alerts.java

package com.example.MyFirstApplication.pages;  

public class Alerts { 
   public String getUser() { 
      return "user1"; 
   } 
}

Luego, cree un archivo de plantilla correspondiente de la siguiente manera:

Alerts.tml

<html t:type = "Newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"  
   xmlns:p = "tapestry:parameter">  
   
   <h3>Alerts</h3> 
   <div class = "alert alert-info"> 
      <h5> Welcome ${user} </h5> 
   </div>
   
</html>

Una alerta tiene tres niveles de gravedad, que son:

  • Info
  • Warn
  • Error

La plantilla anterior se crea mediante una alerta de información. Se define comoalert-info. Puede crear otras severidades según la necesidad.

Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/Alerts

los Form Componentse utiliza para crear un formulario en la página del tapiz para la entrada del usuario. Un formulario puede contener campos de texto, campos de fecha, campos de casilla de verificación, seleccionar opciones, botón de envío y más.

Este capítulo explica en detalle algunos de los componentes de formulario notables.

Componente de casilla de verificación

Un componente de casilla de verificación se utiliza para elegir entre dos opciones mutuamente excluyentes. Cree una página usando la casilla de verificación como se muestra a continuación:

Checkbox.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property;  

public class Checkbox { 
   @Property 
   private boolean check1; 
   
   @Property 
   private boolean check2; 
}

Ahora, crea una plantilla correspondiente Checkbox.tml como se muestra a continuación -

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <h3> checkbox component</h3>  
   <t:form> 
      <t:checkbox t:id = "check1"/> I have a bike <br/> 
      <t:checkbox t:id = "check2"/> I have a car 
   </t:form>  
   
</html>

Aquí, el id del parámetro de la casilla de verificación coincide con el valor booleano correspondiente.

Result - Después de solicitar la página, http: // localhost: 8080 / myFirstApplication / checkbox produce el siguiente resultado.

Componente TextField

El componente TextField permite al usuario editar una sola línea de texto. Crear una paginaText Como se muestra abajo.

Text.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property; 
import org.apache.tapestry5.corelib.components.TextField;public class Text {  
   @Property 
   private String fname;  
   @Property 
   private String lname; 
}

Luego, cree una plantilla correspondiente como se muestra a continuación: Text.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   <p> Form application </p>
   
   <body>  
      <h3> Text field created from Tapestry component </h3> 
      <t:form>  
         <table> 
            <tr> 
               <td> 
                  Firstname: </td> <td><t:textfield t:id = "fname" /> 
               </td> 
               <td>Lastname: </td> <td> <t:textfield t:id = "lname" /> </td> 
            </tr> 
         </table>  
      </t:form>  
   </body> 
   
</html>

Aquí, la página de texto incluye una propiedad denominada fname y lname. Las propiedades acceden a los ID de los componentes.

Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/Text

Componente PasswordField

PasswordField es una entrada de campo de texto especializada para la contraseña. Cree una contraseña de página como se muestra a continuación:

Password.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property; 
import org.apache.tapestry5.corelib.components.PasswordField;  

public class Password {  
   @Property 
   private String pwd; 
}

Ahora, cree un archivo de plantilla correspondiente como se muestra a continuación:

Password.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   <p> Form application </p>  
   <h3> Password field created from Tapestry component </h3> 
   
   <t:form> 
      <table> 
         <tr> 
            <td> Password: </td> 
            <td><t:passwordfield t:id = "pwd"/> </td> 
         </tr> 
      </table> 
   </t:form>
   
</html>

Aquí, el componente PasswordField tiene el parámetro id, que apunta a la propiedad pwd. Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/Password

Componente TextArea

El componente TextArea es un control de texto de entrada de varias líneas. Cree una página TxtArea como se muestra a continuación.

TxtArea.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property; 
import org.apache.tapestry5.corelib.components.TextArea;  

public class TxtArea {  
   @Property 
   private String str;  
}

Luego, cree un archivo de plantilla correspondiente como se muestra a continuación.

TxtArea.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   <h3>TextArea component </h3>
   
   <t:form>
      <table>
         <tr> 
            <td><t:textarea t:id = "str"/>
            </td>
         </tr>
      </table>
   </t:form>
   
</html>

Aquí, el id del parámetro del componente TextArea apunta a la propiedad "str". Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/TxtArea**

Seleccionar componente

El componente Seleccionar contiene una lista desplegable de opciones. Cree una página SelectOption como se muestra a continuación.

SelectOption.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property; 
import org.apache.tapestry5.corelib.components.Select;  

public class SelectOption { 
   @Property 
   private String color0; 
   
   @Property 
   
   private Color1 color1; 
   public enum Color1 { 
      YELLOW, RED, GREEN, BLUE, ORANGE 
   } 
}

Luego, cree una plantilla correspondiente es la siguiente:

SelectOption.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   <p> Form application </p>
   <h3> select component </h3>  
   
   <t:form> 
      <table> 
         <tr> 
            <td> Select your color here: </td> 
            <td> <select t:type = "select" t:id = "color1"></select></td> 
         </tr> 
      </table> 
   </t:form>
   
</html>

Aquí, el componente Seleccionar tiene dos parámetros:

  • Type - El tipo de propiedad es una enumeración.

  • Id - Id apunta a la propiedad Tapestry "color1".

Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/SelectOption

Componente RadioGroup

El componente RadioGroup proporciona un grupo contenedor para componentes Radio. Los componentes Radio y RadioGroup trabajan juntos para actualizar una propiedad de un objeto. Este componente debe envolver otros componentes de radio. Cree una nueva página "Radiobutton.java" como se muestra a continuación -

Radiobutton.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.PersistenceConstants; 
import org.apache.tapestry5.annotations.Persist; 
import org.apache.tapestry5.annotations.Property;  

public class Radiobutton {  
   @Property 
   @Persist(PersistenceConstants.FLASH)  
   private String value; 
}

Luego, cree un archivo de plantilla correspondiente como se muestra a continuación:

Radiobutton.tml

<html t:type = "Newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   <h3>RadioGroup component </h3> 
   
   <t:form>
      <t:radiogroup t:id = "value">
         <t:radio t:id = "radioT" value = "literal:T" label = "Male" /> 
         <t:label for = "radioT"/>    
         <t:radio t:id = "radioF" value = "literal:F" label = "Female"/> 
         <t:label for = "radioF"/>   
      </t:radiogroup>
   </t:form>
   
</html>

Aquí, la identificación del componente de RadioGroup se vincula con la propiedad "valor". Solicitar la página producirá el siguiente resultado.

http://localhost:8080/myFirstApplication/Radiobutton

Enviar componente

Cuando un usuario hace clic en un botón de envío, el formulario se envía a la dirección especificada en la configuración de acción de la etiqueta. Crear una paginaSubmitComponent Como se muestra abajo.

package com.example.MyFirstApplication.pages;  
import org.apache.tapestry5.annotations.InjectPage;  

public class SubmitComponent { 
   @InjectPage 
   private Index page1; 
   Object onSuccess() { 
      return page1; 
   }     
}

Ahora, cree un archivo de plantilla correspondiente como se muestra a continuación.

SubmitComponent.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
   <h3>Tapestry Submit component </h3> 
   
   <body> 
      <t:form> 
         <t:submit t:id = "submit1" value = "Click to go Index"/> 
      </t:form> 
   </body>
   
</html>

Aquí, el componente Enviar envía el valor a la página Índice. Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/SubmitComponent

Validación de formulario

La validación del formulario normalmente ocurre en el servidor después de que el cliente ingresó todos los datos necesarios y luego envió el formulario. Si los datos ingresados ​​por un cliente eran incorrectos o simplemente faltaban, el servidor tendría que enviar todos los datos al cliente y solicitar que el formulario se vuelva a enviar con la información correcta.

Consideremos el siguiente ejemplo simple para comprender el proceso de validación.

Crear una pagina Validate Como se muestra abajo.

Validate.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property; 
import org.apache.tapestry5.PersistenceConstants; 
import org.apache.tapestry5.annotations.Persist;  

public class Validate {  
   @Property 
   @Persist(PersistenceConstants.FLASH) 
   private String firstName; 
   
   @Property 
   @Persist(PersistenceConstants.FLASH) 
   private String lastName; 
}

Ahora, cree un archivo de plantilla correspondiente como se muestra a continuación.

Validate.tml

<html t:type = "newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter"> 
  
   <t:form> 
      <table> 
         <tr> 
            <td><t:label for = "firstName"/>:</td> 
            <td><input t:type = "TextField" t:id = "firstName" 
            t:validate = "required, maxlength = 7" size = "10"/></td>   
         </tr> 
         <tr> 
            <td><t:label for = "lastName"/>:</td> 
            <td><input t:type = "TextField" t:id = "lastName" 
            t:validate = "required, maxLength = 5" size = "10"/></td>  
         </tr>  
      </table>  
      <t:submit t:id = "sub" value =" Form validation"/>  
   </t:form>
   
</html>

La validación de formularios tiene los siguientes parámetros importantes:

  • Max - define el valor máximo, por ejemplo = «valor máximo, 20».

  • MaxDate- define la fecha máxima, por ejemplo, = «fecha máxima, 09/06/2013». Del mismo modo, también puede asignar MinDate.

  • MaxLength - maxLength para, por ejemplo, = «longitud máxima, 80».

  • Min - mínimo.

  • MinLength - Longitud mínima para, por ejemplo, = «longitud mínima, 2».

  • Email - Validación de correo electrónico que utiliza expresiones regulares de correo electrónico estándar ^ \ w [._ \ w] * \ w @ \ w [-._ \ w] * \ w \. \ W2,6 $ o ninguna.

Solicitar la página producirá el siguiente resultado:

http://localhost:8080/myFirstApplication/Validate

AJAX significa Asynchronous JavaScript and XML. Es una técnica para crear aplicaciones web mejores, más rápidas y más interactivas con la ayuda deXML, JSON, HTML, CSS, y JavaScript. AJAX le permite enviar y recibir datos de forma asincrónica sin recargar la página web, por lo que es rápido.

Componente de zona

Un componente de zona se utiliza para proporcionar el contenido (marcado) así como la posición del contenido en sí. Tapestry utiliza internamente el cuerpo del componente de zona para generar el contenido. Una vez generado el contenido dinámico, Tapestry lo enviará al cliente, volverá a procesar los datos en el lugar correcto, activará y animará el HTML para llamar la atención del usuario.

Este componente de zona se utiliza junto con un componente EventLink. Un EventLink tiene la opción de vincularlo a una zona en particular usando elt:zoneatributos. Una vez que la zona está configurada en EventLink, hacer clic en EventLink activará la actualización de la zona. Además, los eventos EventLink (refreshZone) se pueden utilizar para controlar la generación de datos dinámicos.

Un ejemplo simple de AJAX es el siguiente:

AjaxZone.tml

<html t:type = "Newlayout" title = "About MyFirstApplication" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
   
   <body> 
      <h1>Ajax time zone example</h1>  
      <div class = "div1">  
         <a t:type = "eventlink" t:event = "refreshZone" href = "#" 
            t:zone = "timeZone">Ajax Link </a><br/><br/> 
         <t:zone t:id = "timeZone" id = "timeZone">Time zone: ${serverTime}</t:zone> 
      </div>  
   </body>
   
</html>

AjaxZone.java

package com.example.MyFirstApplication.pages;  

import java.util.Date; 
import org.apache.tapestry5.annotations.InjectComponent; 
import org.apache.tapestry5.corelib.components.Zone; 
import org.apache.tapestry5.ioc.annotations.Inject; 
import org.apache.tapestry5.services.Request;  

public class AjaxZone { 
   @Inject 
   private Request request; 
   
   @InjectComponent 
   private Zone timeZone; 
   
   void onRefreshPage() { 
   } 
   
   Object onRefreshZone() { 
      return request.isXHR() ? timeZone.getBody() : null; 
   } 
   
   public Date getServerTime() { 
      return new Date(); 
   } 
}

El resultado se mostrará en: http: // localhost: 8080 / MyFirstApplication / AjaxZone

En este capítulo, discutiremos sobre la integración de BeanEditForm y Grid componentcon Hibernate. Hibernate está integrado en el tapiz a través del módulo de hibernación. Para habilitar el módulo de hibernación, agregue la dependencia tapestry-hibernate y opcionalmentehsqldb en el pom.xmlarchivo. Ahora, configure hibernación a través delhibernate.cfg.xml archivo ubicado en la raíz de la carpeta de recursos.

pom.xml (parcial)

<dependency> 
   <groupId>org.apache.tapestry</groupId> 
   <artifactId>tapestry-hibernate</artifactId> 
   <version>${tapestry-release-version}</version> 
</dependency>  

<dependency> 
   <groupId>org.hsqldb</groupId> 
   <artifactId>hsqldb</artifactId> 
   <version>2.3.2</version> 
</dependency>

Hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC 
   "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
   "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
   <session-factory> 
      <property name = "hibernate.connection.driver_class">
         org.hsqldb.jdbcDriver
      </property> 
      <property name = "hibernate.connection.url">
         jdbc:hsqldb:./target/work/sampleapp;shutdown = true
      </property> 
      <property name = "hibernate.dialect">
         org.hibernate.dialect.HSQLDialect
      </property> 
      
      <property name = "hibernate.connection.username">sa</property> 
      <property name = "hibernate.connection.password"></property> 
      <property name = "hbm2ddl.auto">update</property>
      <property name = "hibernate.show_sql">true</property> 
      <property name = "hibernate.format_sql">true</property> 
   </session-factory> 
</hibernate-configuration>

Veamos cómo crear el employee add page utilizando el componente BeanEditForm y el employee list pageutilizando el componente Grid. La capa de persistencia es manejada por el módulo Hibernate.

Crea una clase para empleados y decórala con la anotación @Entity. Luego, agregue una anotación de validación para los campos relevantes y anotación relacionada con hibernación @Id y @GeneratedValue para el campo de identificación. Además, cree género como tipo de enumeración.

Employee.java

package com.example.MyFirstApplication.entities;  

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id;  
import org.apache.tapestry5.beaneditor.NonVisual; 
import org.apache.tapestry5.beaneditor.Validate;  

@Entity 
public class Employee {  
   @Id 
   @GeneratedValue(strategy = GenerationType.IDENTITY) 
   @NonVisual 
   public Long id;  

   @Validate("required") 
   public String firstName;  
 
   @Validate("required") 
   public String lastName; 

   @Validate("required") 
   public String userName;  

   @Validate("required") 
   public String password;  

   @Validate("required") 
   public String email;  
   public String phone;  

   @Validate("required") 
   public String Street;  

   @Validate("required") 
   public String city;  

   @Validate("required") 
   public String state;  

   @Validate("required,regexp=^\\d{5}(-\\d{4})?$") 
   public String zip; 
} 
Gender.java (enum)  
package com.example.MyFirstApplication.data;  

public enum Gender { 
   Male, Female 
}

Cree la página de la lista de empleados, ListEmployee.java en la nueva carpeta empleado en las páginas y el archivo de plantilla correspondiente ListEmployee.tml en /src/main/resources/pages/employeecarpeta. Tapestry proporciona una URL corta para las subcarpetas al eliminar los datos repetidos.

Por ejemplo, se puede acceder a la página ListEmployee mediante una URL normal - (/ employee / listemployee) y mediante la URL corta - (/ employee / list).

Inyecte la sesión de Hibernate en la página de la lista usando la anotación @Inject. Definir una propiedadgetEmployeesen la página de lista y rellénela con los empleados que utilizan el objeto de sesión inyectado. Complete el código para la clase de empleado como se muestra a continuación.

ListEmployee.java

package com.example.MyFirstApplication.pages.employee;  

import java.util.List;  
import org.apache.tapestry5.annotations.Import; 
import org.apache.tapestry5.ioc.annotations.Inject;  
import org.hibernate.Session; 
import com.example.MyFirstApplication.entities.Employee; 
import org.apache.tapestry5.annotations.Import;  
@Import(stylesheet="context:mybootstrap/css/bootstrap.css") 

public class ListEmployee { 
   @Inject 
   private Session session; 
   
   public List<Employee> getEmployees() { 
      return session.createCriteria(Employee.class).list(); 
   } 
}

Cree el archivo de plantilla para la clase ListEmployee. La plantilla tendrá dos componentes principales, que son:

  • PageLink - Crear página de enlace de empleado.

  • Grid- Se utiliza para representar los detalles del empleado. El componente de cuadrícula tiene atributos de fuentes para inyectar la lista de empleados e incluye atributos para incluir los campos que se van a representar.

ListEmployee.tml (enumere todos los empleados)

<html t:type = "simplelayout" title = "List Employee" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <h1>Employees</h1> 
   
   <ul> 
      <li><t:pagelink page = "employee/create">Create new employee</t:pagelink></li> 
   </ul>  
   <t:grid source = "employees" 
      include = "userName,firstName,lastName,gender,dateOfBirth,phone,city,state"/>  
</html>

Cree un archivo de plantilla de creación de empleados e incluya el componente BeanEditForm. El componente tiene los siguientes atributos:

  • object - Incluye fuente.

  • reorder - Define el orden de los campos a renderizar.

  • submitlabel - El mensaje del botón de envío del formulario

La codificación completa es la siguiente:

<html t:type = "simplelayout" title = "Create New Address" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">  
   <t:beaneditform  
      object = "employee"  
      submitlabel = "message:submit-label" 
      reorder = "userName,password,firstName,lastName,
      dateOfBirth,gender,email,phone,s treet,city,state,zip" />  
</html>

Cree la clase de creación de empleados e incluya sesión, propiedad del empleado, página de lista (enlace de navegación) y defina el evento OnSuccess (lugar para actualizar los datos) del componente. Los datos de la sesión se conservan en la base de datos mediante la sesión de hibernación.

La codificación completa es la siguiente:

package com.example.MyFirstApplication.pages.employee;  

import com.example.MyFirstApplication.entities.Employee; 
import com.example.MyFirstApplication.pages.employee.ListEmployee; 
import org.apache.tapestry5.annotations.InjectPage; 
import org.apache.tapestry5.annotations.Property;  
import org.apache.tapestry5.hibernate.annotations.CommitAfter; 
import org.apache.tapestry5.ioc.annotations.Inject; 
import org.hibernate.Session;  

public class CreateEmployee { 
   @Property 
   private Employee employee;  
   @Inject 
   private Session session;  
   @InjectPage 
   private ListEmployee listPage;  
   @CommitAfter 
   Object onSuccess() { 
      session.persist(employee);  
      return listPage; 
   } 
}

Añade el CreateEmployee.propertiese incluir el mensaje que se utilizará en las validaciones de formularios. El código completo es el siguiente:

zip-regexp=^\\d{5}(-\\d{4})?$ 
zip-regexp-message = Zip Codes are five or nine digits. Example: 02134 or 901251655. 
submit-label = Create Employee

La captura de pantalla de la página de creación de empleados y la página de listado se muestran a continuación:

Cada aplicación web debe tener alguna forma de almacenar ciertos datos del usuario, como el objeto del usuario, las preferencias del usuario, etc. Por ejemplo, en una aplicación de carrito de compras, los artículos / productos seleccionados por el usuario deben guardarse en un depósito temporal (carrito) hasta que el usuario lo prefiera. para comprar los productos. Podemos guardar los artículos en una base de datos, pero será demasiado caro ya que no todos los usuarios van a comprar los artículos seleccionados. Entonces, necesitamos un arreglo temporal para almacenar / conservar los artículos. Apache Tapestry Proporciona dos formas de conservar los datos y son:

  • Datos de la página de persistencia
  • Almacenamiento de sesiones

Ambos tienen sus propias ventajas y limitaciones. Lo comprobaremos en los siguientes apartados.

Datos de la página de persistencia

Los datos de la página de persistencia es un concepto simple para conservar datos en una sola página entre solicitudes y también se denomina como Page Level Persistence. Se puede hacer usando el@Persist anotación.

@Persist 
public int age;

Una vez que se anota un campo con @Persist, el valor del campo se mantendrá a lo largo de la solicitud y, si el valor se cambia durante la solicitud, se reflejará cuando se acceda a él la próxima vez. Apache Tapestry proporciona cinco tipos de estrategias para implementar el concepto @Persist. Son los siguientes:

  • Session Strategy - Los datos se conservan utilizando la sesión y es una estrategia predeterminada.

  • Flash Strategy- Los datos también se conservan utilizando Session, pero es de muy corta duración. Los datos estarán disponibles en una sola solicitud posterior.

@Persist(PersistenceConstants.FLASH) 
private int age;
  • Client Strategy - Los datos se conservan en el lado del cliente, como la cadena de consulta de URL, el campo oculto en el formulario, etc.

@Persist(PersistenceConstants.FLASH) 
private int age;
  • Hibernate Entity Strategy- Los datos se conservan utilizando el módulo Hibernate como Entidad. La entidad se almacenará en Hibernate y su referencia (nombre de clase Java y su clave principal) se guardará como token enHttpSession. La entidad se restaurará utilizando el token disponible en HttpSession.

@Persist(HibernatePersistenceConstants.ENTITY) 
private Category category;
  • JPA Entity Strategy- Los datos se conservan mediante un módulo JPA. Solo podrá almacenar Entity.

@Persist(JpaPersistenceConstants.ENTITY) 
private User user;

Almacenamiento de sesiones

El almacenamiento de sesiones es un concepto avanzado que se utiliza para almacenar datos que deben estar disponibles en las páginas, como los datos en el asistente de varias páginas, los detalles del usuario registrado, etc. El almacenamiento de sesiones ofrece dos opciones, una para almacenar objetos complejos y otra para almacenar valores simples

  • Session Store Object - Se utiliza para almacenar objetos complejos.

  • Session Attributes - Se utiliza para almacenar valores simples.

Objeto de almacenamiento de sesión (SSO)

Se puede crear un SSO usando @SessionStoreanotación. El SSO almacenará el objeto usando el tipo de objeto. Por ejemplo, elCart Objectse almacenará utilizando un nombre de clase Cart como token. Por tanto, cualquier objeto complejo se puede almacenar una vez en una aplicación (uno por usuario).

public class MySSOPage { 
   @SessionState 
   private ShoppingCart cart; 
}

Un SSO es una tienda especializada y debe usarse para almacenar solo objetos complejos / especiales. Los tipos de datos simples también se pueden almacenar usando un SSO, pero el almacenamiento de tipos de datos simples como String hace que solo almacene un valor de “String” en la aplicación. El uso de un solo valor de "Cadena" en la aplicación simplemente no es posible. Puede usar tipos de datos simples ya que Apache Tapestry proporciona atributos de sesión.

Atributos de sesión

Los atributos de sesión permiten que los datos se almacenen por nombre en lugar de por su tipo.

public class MyPage { 
   @SessionAttribute  
   private String loggedInUsername; 
}

De forma predeterminada, Atributos de sesión utiliza el nombre del campo para hacer referencia a los datos de la sesión. Podemos cambiar el nombre de referencia mediante el parámetro de anotación como se muestra a continuación:

public class MyPage { 
   @SessionAttribute("loggedInUserName") 
   private String userName; 
}

Uno de los principales problemas al usar el nombre como referencia de sesión es que podemos usar accidentalmente el mismo nombre en más de una clase / página. En este caso, los datos almacenados pueden cambiar inesperadamente. Para solucionar este problema, será mejor usar el nombre junto con el nombre de la clase / página y el nombre del paquete comocom.myapp.pages.register.email, donde com.myapp.pages es el nombre del paquete, register es el nombre de la página / clase y, finalmente, el correo electrónico es el nombre variable (que se almacenará).

En este capítulo, analizaremos en detalle algunas características avanzadas de Apache Tapestry.

Inversión de control

Tapestry proporciona una biblioteca de Inversión de control incorporada. Tapestry está profundamente integrado en IoC y utiliza IoC para todas sus funciones. La configuración de Tapestry IoC se basa en Java mismo en lugar de XML como muchos otros contenedores de IoC. Los módulos basados ​​en Tapestry IoC se empaquetan en un archivo JAR y simplemente se colocan en la ruta de clases sin configuración. El uso de Tapestry IoC se basa en la ligereza, lo que significa:

  • Pequeñas interfaces de dos o tres métodos.

  • Pequeños métodos con dos o tres parámetros.

  • Comunicación anónima a través de eventos, en lugar de invocaciones de métodos explícitos.

Módulos

El módulo es una forma de ampliar la funcionalidad de la aplicación Tapestry. Tapestry tiene tanto módulos incorporados como una gran cantidad de módulos de terceros. Hibernate es uno de los módulos interesantes y muy útiles proporcionados por Tapestry. También tiene módulos que integran JMX, JPA, Spring Framework, JSR 303 Bean Validation, JSON, etc. Algunos de los módulos de terceros notables son:

  • Tapestry-Cayenne
  • Tapestry5-googleanalytics
  • Cuadrilla de tapiz 5 - Tapestry5-HighCharts
  • Cuadrilla de tapiz 5 - Tapestry5-jqPlot
  • Cuadrilla de tapiz 5 - Tapestry5-Jquery
  • Pandilla de tapiz 5 - Tapestry5-Jquery-mobile
  • Cuadrilla de tapiz 5 - Tapestry5-Portlet

Excepciones de tiempo de ejecución

Una de las mejores características del tapiz es Detailed Error Reporting. Tapestry ayuda a un desarrollador al proporcionar informes de excepciones de última generación. El informe de excepción de tapiz es HTML simple con información detallada. Cualquiera puede entender fácilmente el informe. Tapestry muestra el error en HTML y guarda la excepción en un texto sin formato con la fecha y hora en que ocurrió la excepción. Esto ayudará al desarrollador a verificar la excepción en el entorno de producción también. El desarrollador puede confiar en solucionar cualquier problema, como plantillas rotas, valores nulos inesperados, solicitud no coincidente, etc.

Recarga de plantillas y clases en vivo

Tapestry recargará las plantillas y clases automáticamente cuando se modifiquen. Esta función permite el reflejo inmediato de los cambios de la aplicación sin pasar por el ciclo de compilación y prueba. Además, esta característica mejora enormemente la productividad del desarrollo de la aplicación.

Considere que el paquete raíz de la aplicación es org.example.myfirstapp. Luego, las clases en las siguientes rutas se escanean para recargar.

  • org.example.myfirstapp.pages
  • org.example.myfirstapp.components
  • org.example.myfirstapp.mixins
  • org.example.myfirstapp.base
  • org.example.myfirstapp.services

La recarga de la clase en vivo se puede deshabilitar configurando el modo de producción en true en AppModule.java.

configuration.add(SymbolicConstants.PRODUCTION_MODE,”false”);

Examen de la unidad

La prueba unitaria es una técnica mediante la cual se prueban páginas y componentes individuales. Tapestry ofrece opciones sencillas para unificar páginas y componentes de prueba.

Prueba unitaria de una página: tapiz proporciona una clase PageTesterpara probar la aplicación. Esto actúa como navegador y como contenedor de servlets. Representa la página sin el navegador en el lado del servidor y el documento resultante se puede verificar para una representación correcta. Considere una página simpleHello, que muestra hola y el texto de saludo se incluye dentro de un elemento html con id hello_id. Para probar esta función, podemos usar PageTester como se muestra a continuación:

public class PageTest extends Assert { 
   @Test 
   public void test1() { 
      Sring appPackage = "org.example.myfirstapp"; // package name 
      String appName = "App1"; // app name 
      PageTester tester = new PageTester(appPackage, appName, "src/main/webapp"); 
      Document doc = tester.renderPage("Hello"); 
      assertEquals(doc.getElementById("hello_id").getChildText(), "hello"); 
   } 
}

PageTester también ofrece la opción de incluir información de contexto, envío de formularios, navegación de enlaces, etc., además de representar la página.

Pruebas integradas

Las pruebas integradas ayudan a probar la aplicación como un módulo en lugar de verificar las páginas individuales como en las pruebas unitarias. En las pruebas integradas, se pueden probar varios módulos juntos como una unidad. Tapestry proporciona una pequeña biblioteca llamadaTapestry Test Utilitiespara hacer pruebas integradas. Esta biblioteca se integra con la herramienta de prueba Selenium para realizar la prueba. La biblioteca proporciona una clase baseSeleniumTestCase, que inicia y administra el servidor Selenium, el cliente Selenium y la Instancia Jetty.

Uno de los ejemplos de pruebas integradas es el siguiente:

import org.apache.tapestry5.test.SeleniumTestCase; 
import org.testng.annotations.Test;  

public class IntegrationTest extends SeleniumTestCase { 
   @Test 
   public void persist_entities() {  
      open("/persistitem"); 
      assertEquals(getText("//span[@id='name']").length(), 0); 
      clickAndWait("link = create item"); 
      assertText("//span[@id = 'name']", "name"); 
   } 
}

Panel de desarrollo

El panel de desarrollo es la página predeterminada que se utiliza para identificar / resolver los problemas en su aplicación. Se accede al panel mediante la URLhttp://localhost:8080/myfirstapp/core/t5dashboard. El tablero muestra todas las páginas, servicios y bibliotecas de componentes disponibles en la aplicación.

Compresión de respuesta

Tapestry comprime automáticamente la respuesta usando GZIP compressiony transmítalo al cliente. Esta característica reducirá el tráfico de la red y ayudará a una entrega más rápida de la página. La compresión se puede configurar mediante el símbolotapestry.min-gzip-sizeen AppModule.java. El valor predeterminado es 100 bytes. Tapestry comprimirá la respuesta una vez que el tamaño de la respuesta cruce los 100 bytes.

Seguridad

Tapestry ofrece muchas opciones para proteger la aplicación contra vulnerabilidades de seguridad conocidas en la aplicación web. Algunas de estas opciones se enumeran a continuación:

  • HTTPS - Las páginas de tapiz se pueden anotar con @Secure para que sea una página segura y accesible por el https protocol solamente.

  • Page access control - Controlar la página a la que accederá un determinado usuario únicamente.

  • White-Listed Page - Las páginas de tapiz se pueden anotar con un @WhitelistAccessOnly para hacerlo accesible solo a través del localhost.

  • Asset Security- Bajo tapiz, solo se puede acceder a ciertos tipos de archivos. Se puede acceder a otros solo cuando elMD5 hash del archivo se proporciona.

  • Serialized Object Date - Tapestry integra un HMAC en datos de objetos Java serializados y los envía al cliente para evitar la manipulación de mensajes.

  • Cross Site Request Forgery- Tapiz ofrece un 3 er módulo de parte llamada-csrf-protección tapiz para prevenir cualquier ataque CSRF.

  • Security Framework integration- Tapestry no se bloquea en una única implementación de autenticación / autorización. Tapestry se puede integrar con cualquier marco de autenticación popular.

Inicio sesión

Tapestry proporciona un amplio soporte para el registro, el registro automático del progreso de la aplicación mientras se ejecuta. Tapestry utiliza la biblioteca de registro de Java de facto,SLF4J. La anotación@Logpuede estar en cualquier método de componente para emitir la entrada y salida del método y también la posible excepción. Además, el objeto registrador proporcionado por Tapestry se puede inyectar en cualquier componente utilizando el@Inject anotación como se muestra a continuación -

public class MyPage { 
   @Inject 
   private Logger logger; 
   
   // . . . 
    
   void onSuccessFromForm() { 
      logger.info("Changes saved successfully"); 
   } 
     
   @Log 
   void onValidateFromForm() { 
      // logic 
   } 
}

Finalmente, ahora podemos decir que Apache Tapestry ofrece las mejores formas de crear aplicaciones concisas, escalables, sostenibles, robustas y habilitadas para Ajax. Tapestry se puede integrar con cualquier aplicación Java de terceros. También puede ayudar a crear una gran aplicación web, ya que es bastante fácil y rápido.