Учебники

Apache Tapestry — Краткое руководство

Apache Tapestry — Обзор

Apache Tapestry — это веб-инфраструктура с открытым исходным кодом, написанная на Java. Это компонентный веб-фреймворк . Компоненты гобелена являются классами Java. Они не наследуются ни от базового класса, специфичного для фреймворка, ни от реализации интерфейса, а представляют собой простые POJO (простые старые объекты Java).

Важной особенностью Java, используемой гобеленом, является аннотация . Веб-страницы Tapestry создаются с использованием одного или нескольких компонентов, каждый из которых имеет шаблон на основе XML и класс компонентов, украшенный множеством аннотаций Tapestry. Tapestry может создавать что угодно, от крошечного одностраничного веб-приложения до огромного, состоящего из сотен страниц.

Преимущества гобелена

Некоторые из преимуществ, предоставляемых гобеленом, —

  • Высоко масштабируемые веб-приложения.
  • Адаптивный API.
  • Быстрые и зрелые рамки.
  • Управление хранением постоянного состояния.
  • Встроенная инверсия управления.

Особенности гобелена

Гобелен имеет следующие особенности —

  • Перегрузка живого класса
  • Четкая и подробная отчетность об исключениях
  • Статическая структура, динамическое поведение.
  • Широкое использование простых старых объектов Java (POJO)
  • Код меньше, доставь больше.

Почему Гобелен?

У Java уже есть много веб-фреймворков, таких как JSP, Struts и т. Д. Тогда зачем нам нужен еще один фреймворк? Большинство современных Java Web Framework являются сложными и имеют крутой курс обучения. Они устарели и требуют циклов компиляции, тестирования и развертывания для каждого обновления.

С другой стороны, Tapestry предоставляет современный подход к программированию веб-приложений, обеспечивая перезагрузку классов в реальном времени . В то время как другие фреймворки представляют множество интерфейсов, абстрактных и базовых классов, Tapestry просто представляет небольшой набор аннотаций и все еще предоставляет возможность писать большие приложения с богатой поддержкой AJAX.

Apache Tapestry — Архитектура

Гобелен пытается максимально использовать доступные возможности Java. Например, все страницы Гобелена просто POJO. Он не требует каких-либо пользовательских интерфейсов или базового класса для написания приложения. Вместо этого он использует аннотацию (облегченный вариант для расширения функциональности класса Java) для предоставления функций. Он основан на проверенном в бою API сервлетов Java и реализован в виде фильтра сервлетов. Он предоставляет новое измерение веб-приложению, и программирование довольно простое, гибкое, понятное и надежное.

Workflow

Давайте обсудим последовательность действий, выполняемых при запросе страницы гобелена.

Workflow

Шаг 1Сервлет Java получает запрос страницы. Этот сервлет Java настроен таким образом, что входящий запрос будет перенаправлен на гобелен. Конфигурация выполняется в файле web.xml, как указано в следующей программе. Filter и Filter Mapping tag перенаправляет весь запрос в 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> 

Шаг 2Фильтр Tapestry вызывает сервис HttpServletRequestHandler с помощью метода Service () .

Шаг 3HttpServletRequestHandler сохраняет запрос и ответ в RequestGlobals . Он также упаковывает запрос и ответ в качестве объекта запроса и ответа и отправляет его в RequestHandler.

Шаг 4RequestHandler — это абстракция поверх HttpServletRequest Servlet API. Некоторые из характерных особенностей гобелена сделаны в разделе RequestHandler . Функцию гобелена можно расширить, написав фильтр в RequestHandler. RequestHandler предоставляет несколько встроенных фильтров, которые включают в себя:

  • CheckForUpdates Filter — отвечает за перезагрузку класса в реальном времени. Этот фильтр проверяет классы Java на наличие изменений и обновляет приложение по мере необходимости.

  • Фильтр локализации — определяет местоположение пользователя и обеспечивает поддержку локализации для приложения.

  • Фильтр StaticFiles — определяет статический запрос и прерывает процесс. Как только процесс прерван, сервлет Java берет на себя управление и обрабатывает запрос.

  • Фильтр ошибок — ловит необнаруженное исключение и представляет страницу отчета об исключении.

CheckForUpdates Filter — отвечает за перезагрузку класса в реальном времени. Этот фильтр проверяет классы Java на наличие изменений и обновляет приложение по мере необходимости.

Фильтр локализации — определяет местоположение пользователя и обеспечивает поддержку локализации для приложения.

Фильтр StaticFiles — определяет статический запрос и прерывает процесс. Как только процесс прерван, сервлет Java берет на себя управление и обрабатывает запрос.

Фильтр ошибок — ловит необнаруженное исключение и представляет страницу отчета об исключении.

RequestHandler также изменяет и сохраняет запрос и ответ в RequestQlobals и вызывает службу MasterDispatcher.

Шаг 5MasterDispatcher отвечает за рендеринг страницы, вызывая несколько диспетчеров определенного порядка. Четыре главных диспетчера, вызываемые MasterDispatcher, следующие:

  • RootPath Dispatcher — распознает корневой путь «/» запроса и отображает его так же, как стартовая страница.

  • Диспетчер активов — он распознал запрос актива (актива Java), проверив шаблон URL / assets / и отправил запрошенные активы в виде потоков байтов.

  • PageRender Dispatcherосновная часть операций с гобеленами выполняется в PageRender Dispatcher и следующем диспетчере компонентов Dispatcher. Этот диспетчер распознает конкретную страницу этого запроса и его контекст активации (дополнительная информация). Затем он отображает эту конкретную страницу и отправляет ее клиенту. Например, если URL-адрес запроса / product / 12123434, диспетчер проверит, доступен ли какой-либо класс с именем product / 12123434. Если он найден, он вызывает класс product / 12123434, генерирует ответ и отправляет его клиенту. Если нет, он проверяет класс продукта. Если найдено, он вызывает класс продукта с дополнительной информацией 121234434, генерирует ответ и отправляет его клиенту. Эта дополнительная информация называется «Активация контекста». Если класс не найден, он просто перенаправляет запрос в диспетчер компонентов.

  • Компонент Dispatcher — Компонент Dispatcher сопоставляет URL-адрес страницы с шаблоном — / <class_name> / <component_id>: <event_type> / <активации_context>. Например, / product / grid: sort / asc представляет класс продукта, компонент сетки, тип sortevent и контекст активации asc. Здесь event_type является необязательным, и если ничего не указано, будет инициировано действие типа события по умолчанию. Обычно ответ диспетчера компонентов заключается в отправке перенаправления клиенту. В основном, перенаправление будет соответствовать PageRender Dispatcher в следующем запросе, и правильный ответ будет отправлен клиенту.

RootPath Dispatcher — распознает корневой путь «/» запроса и отображает его так же, как стартовая страница.

Диспетчер активов — он распознал запрос актива (актива Java), проверив шаблон URL / assets / и отправил запрошенные активы в виде потоков байтов.

PageRender Dispatcherосновная часть операций с гобеленами выполняется в PageRender Dispatcher и следующем диспетчере компонентов Dispatcher. Этот диспетчер распознает конкретную страницу этого запроса и его контекст активации (дополнительная информация). Затем он отображает эту конкретную страницу и отправляет ее клиенту. Например, если URL-адрес запроса / product / 12123434, диспетчер проверит, доступен ли какой-либо класс с именем product / 12123434. Если он найден, он вызывает класс product / 12123434, генерирует ответ и отправляет его клиенту. Если нет, он проверяет класс продукта. Если найдено, он вызывает класс продукта с дополнительной информацией 121234434, генерирует ответ и отправляет его клиенту. Эта дополнительная информация называется «Активация контекста». Если класс не найден, он просто перенаправляет запрос в диспетчер компонентов.

Компонент Dispatcher — Компонент Dispatcher сопоставляет URL-адрес страницы с шаблоном — / <class_name> / <component_id>: <event_type> / <активации_context>. Например, / product / grid: sort / asc представляет класс продукта, компонент сетки, тип sortevent и контекст активации asc. Здесь event_type является необязательным, и если ничего не указано, будет инициировано действие типа события по умолчанию. Обычно ответ диспетчера компонентов заключается в отправке перенаправления клиенту. В основном, перенаправление будет соответствовать PageRender Dispatcher в следующем запросе, и правильный ответ будет отправлен клиенту.

Apache Tapestry — Установка

В этой главе мы обсудим, как установить Tapestry на нашу машину.

необходимое условие

Единственная зависимость Tapestry — это Core Java . Гобелен разрабатывается самостоятельно, без использования сторонних библиотек / фреймворков. Даже библиотека IoC, используемая гобеленами, разработана с нуля. Веб-приложение, написанное на гобелене, может быть построено и развернуто с самой консоли.

Мы можем использовать Maven, Eclipse и Jetty для улучшения опыта разработки. Maven предоставляет шаблоны быстрого запуска приложений и опции для размещения приложений в Jetty, де-факто сервере разработки Java. Eclipse предоставляет широкие возможности управления проектами и хорошо интегрируется с Maven.

Идеальная разработка гобеленовых приложений требует следующего —

  • Java 1.6 или новее
  • Apache Maven
  • Eclipse IDE
  • Jetty Server

Проверьте установку Maven

Надеюсь, вы установили Maven на свой компьютер. Чтобы проверить установку Maven, введите команду, приведенную ниже —

mvn --version

Вы можете увидеть ответ, как показано ниже —

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"

Если Maven не установлен, загрузите и установите последнюю версию maven, посетив веб-сайт Maven .

Скачать Гобелен

Последняя версия гобелена является 5.4 и может быть загружена с веб-сайта Гобелен . Достаточно скачать бинарный пакет. Если мы используем шаблон быстрого запуска Maven, то нет необходимости загружать Гобелен отдельно. Maven автоматически загружает необходимые баночки с гобеленами и настраивает приложение. В следующей главе мы обсудим, как создать базовое приложение для гобеленов с использованием Maven.

Apache Tapestry — Быстрый старт

После установки Tapestry, давайте создадим новый начальный проект, используя Maven, как показано ниже —

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

Вы можете увидеть ответ, как показано ниже —

[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)

После того, как Maven соберет все операции, выберите архетип, чтобы создать проект Tapestry 5 QuickStart следующим образом:

Выберите архетип

https://tapestry.apache.org → org.apache.tapestry: быстрый запуск (Проект быстрого запуска Tapestry 5)

https://tapestry.apache.org → org.apache.tapestry: гобелен-архетип (Гобелен 4.1.6 архетип)

Выберите номер или примените фильтр (формат: [groupId:] artifactId, с учетом регистра):: 1

Теперь вы получите ответ, как показано ниже —

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 

Извлеките номер версии QuickStart следующим образом —

Choose a number: 5: 5

Здесь проект QuickStart принимает версию для опции 5, «5.4.1». Теперь, Гобелен архетип запрашивает следующую информацию одну за другой следующим образом —

  • 5.1 groupId — Определите значение для свойства ‘groupId’:: com.example

  • 5.2 artifactId — Определите значение для свойства ‘artifactId’:: Myapp

  • 5.3 версия — Определите значение для свойства ‘версия’: 1.0-SNAPSHOT::

  • 5.4 имя пакета — Определите значение для свойства package: com.example:: com.example.Myapp

5.1 groupId — Определите значение для свойства ‘groupId’:: com.example

5.2 artifactId — Определите значение для свойства ‘artifactId’:: Myapp

5.3 версия — Определите значение для свойства ‘версия’: 1.0-SNAPSHOT::

5.4 имя пакета — Определите значение для свойства package: com.example:: com.example.Myapp

Теперь ваш экран запрашивает подтверждение от вас —

Подтвердите настройки свойств —

  • groupId — com.example

  • artifactId — Myapp

  • версия — 1.0-SNAPSHOT

  • пакет — com.example.Myapp

groupId — com.example

artifactId — Myapp

версия — 1.0-SNAPSHOT

пакет — com.example.Myapp

Проверьте все свойства и подтвердите изменения, используя опцию, показанную ниже —

 Y: : Y 

Вы увидите экран, подобный показанному ниже.

[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] ---------------------------------------------------------------------------------

Здесь вы успешно создали проект Tapestry Quick Start. Перейдите в местоположение только что созданного каталога Myapp с помощью следующей команды и начните кодирование.

cd Myapp 

Запустить приложение

Чтобы запустить скелетный проект, используйте следующую команду.

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

Вы получаете такой экран,

[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

На данный момент мы создали базовый проект Quick Start в Tapestry. Чтобы просмотреть запущенное приложение в веб-браузере, просто введите следующий URL-адрес в адресную строку и нажмите ввод —

https: // локальный: 8080 / MyApp

Здесь myapp — это имя приложения, а порт приложения в режиме разработки по умолчанию — 8080.

Использование Eclipse

В предыдущей главе мы обсуждали, как создать приложение быстрого запуска Tapestry в CLI. В этой главе рассказывается о создании каркасного приложения в Eclipse IDE .

Давайте используем архетип Maven для создания скелетного приложения. Чтобы настроить новое приложение, вы можете выполнить шаги, указанные ниже.

Шаг 1: Откройте Eclipse IDE

Откройте Eclipse и выберите «Файл» → «Новый» → «Проект …», как показано на следующем снимке экрана.

Открытое Затмение

Теперь выберите Maven → Maven.

Примечание. Если Maven не настроен, настройте и создайте проект.

После выбора проекта Maven нажмите кнопку «Далее» и еще раз нажмите кнопку «Далее».

Maven Project

После этого вы получите экран, где вы должны выбрать опцию конфигурации. Как только он будет настроен, вы получите следующий экран.

Настроить опцию

Шаг 2: Конфигурация каталога

После того, как первый шаг сделан, вы должны нажать Add Remote Catalog . Затем добавьте следующие изменения, как показано на следующем снимке экрана.

Удаленный каталог

Теперь добавлен каталог гобеленов Apache. Затем выберите опцию фильтра org.apache.tapestry quickstart 5.4.1, как показано ниже.

Добавлен каталог

Затем нажмите Next, и появится следующий экран.

Поле Id группы

Шаг 3: Настройте GroupId, ArtifactId, версию и пакет

Добавьте следующие изменения в конфигурацию каталога гобеленов.

Изменения конфигурации

Затем нажмите кнопку Готово, теперь мы создали первое скелетное приложение. При первом использовании Maven создание проекта может занять некоторое время, так как Maven загружает множество зависимостей JAR для Maven, Jetty и Tapestry. После завершения работы Maven вы увидите новый каталог MyFirstApplication в представлении Package Explorer.

Шаг 4: Запустите приложение с помощью сервера Jetty

Вы можете использовать Maven для запуска Jetty напрямую. Щелкните правой кнопкой мыши проект MyFirstApplication в представлении Package Explorer и выберите Run As → Maven Build… откроется экран, показанный ниже.

Jetty Server

В диалоговом окне конфигурации введите параметр целей как «jetty: run», затем нажмите кнопку «Run».

Вариант целей

После инициализации Jetty вы увидите следующий экран в своей консоли.

Причал инициализирован

Шаг 5: Запустите в веб-браузере

Введите следующий URL-адрес, чтобы запустить приложение в веб-браузере —

https: // loclhost: 8080 / MyFirstApplication

Запустить веб-браузер

Шаг 6: остановка сервера Jetty

Чтобы остановить сервер Jetty, щелкните значок красного квадрата на консоли, как показано ниже.

Остановить сервер

Apache Tapestry — Макет проекта

Вот макет исходного кода, созданного Maven Quickstart CLI . Кроме того, это рекомендуемый макет стандартного приложения для гобеленов.

├── 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

Макет по умолчанию организован как внутренний формат файла WAR . Использование формата WAR помогает запустить приложение без упаковки и развертывания. Этот макет является всего лишь предложением, но приложение может быть организовано в любом формате, если при развертывании оно упаковано в правильный формат WAR.

Исходный код можно разделить на следующие четыре основных раздела.

  • Код Java — Все исходные коды Java находятся в папке / src / main / java . Классы страниц гобелена помещаются в папку «Страницы», а классы компонентов гобелена помещаются в папку компонентов. Классы обслуживания гобеленов находятся в папке сервисов.

  • Ресурсы ClassPath. В Tapestry большинство классов имеют связанные ресурсы (XML-шаблон, файлы JavaScript и т. Д.). Эти ресурсы находятся в папке / src / main / resources . Классы страниц Tapestry имеют связанные ресурсы в папке «Pages», а классы компонентов Tapestry — связанные ресурсы в папке Components. Эти ресурсы упакованы в папку WEB-INF / classes WAR.

  • Ресурсы контекста. Это статические ресурсы веб-приложения, такие как изображения, таблица стилей и библиотека / модули JavaScript . Они обычно помещаются в папку / src / main / webapp и называются Context Resources . Кроме того, файл описания веб-приложения (Java-сервлета), web.xml, находится в папке контекстных ресурсов WEB-INF .

  • Тестовый код — это дополнительные файлы, используемые для тестирования приложения и помещенные в папки src / test / java и src / test / Resources. Они не упакованы в WAR.

Код Java — Все исходные коды Java находятся в папке / src / main / java . Классы страниц гобелена помещаются в папку «Страницы», а классы компонентов гобелена помещаются в папку компонентов. Классы обслуживания гобеленов находятся в папке сервисов.

Ресурсы ClassPath. В Tapestry большинство классов имеют связанные ресурсы (XML-шаблон, файлы JavaScript и т. Д.). Эти ресурсы находятся в папке / src / main / resources . Классы страниц Tapestry имеют связанные ресурсы в папке «Pages», а классы компонентов Tapestry — связанные ресурсы в папке Components. Эти ресурсы упакованы в папку WEB-INF / classes WAR.

Ресурсы контекста. Это статические ресурсы веб-приложения, такие как изображения, таблица стилей и библиотека / модули JavaScript . Они обычно помещаются в папку / src / main / webapp и называются Context Resources . Кроме того, файл описания веб-приложения (Java-сервлета), web.xml, находится в папке контекстных ресурсов WEB-INF .

Тестовый код — это дополнительные файлы, используемые для тестирования приложения и помещенные в папки src / test / java и src / test / Resources. Они не упакованы в WAR.

Соглашение по конфигурации

Apache Tapestry следует Соглашению по Конфигурации в каждом аспекте программирования. У каждой функции фреймворка есть разумное соглашение по умолчанию.

Например, как мы узнали из главы «Макет проекта», все страницы должны быть помещены в папку / src / main / java / «package_path» / pages / для того, чтобы они рассматривались как страницы гобелена.

В другом смысле нет необходимости настраивать определенный класс Java как страницы гобелена. Достаточно поместить класс в заранее определенное место. В некоторых случаях странно следовать стандартному соглашению Гобеленов.

Например, компонент Tapestry может иметь метод setupRender, который будет запущен в начале фазы рендеринга. Разработчик может захотеть использовать свое собственное имя, скажем, initializeValue . В этой ситуации Tapestry предоставляет аннотацию для переопределения соглашений, как показано в следующем блоке кода.

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

Оба способа программирования действительны в Гобелене. Короче говоря, конфигурация Tapestry по умолчанию довольно минимальна. Только Apache Tapestry Filter (Java Servlet Filter) должен быть настроен в «Web.xml» для правильной работы приложения.

Tapestry предоставляет еще один способ настройки приложения, и он называется AppModule.java .

Apache Tapestry — Аннотация

Аннотация — это очень важная функция, используемая Tapestry для упрощения разработки веб-приложений. Гобелен предоставляет множество пользовательских аннотаций. Он имеет аннотацию для классов, методов и полей-членов. Как обсуждалось в предыдущем разделе, Аннотация также может использоваться для переопределения соглашения по умолчанию для функции. Аннотации гобеленов сгруппированы по четырем основным категориям и имеют следующий вид.

Компонентная аннотация

Используется в классах страниц, компонентов и миксинов. Некоторые из полезных аннотаций —

  • @Property — применимо к полям. Используется для преобразования поля в свойство гобелена.

  • @Parameter — применимо к полям. Используется для указания поля в качестве параметра компонента.

  • @Environmental — это применимо к полям. Используется для совместного использования частного поля между различными компонентами.

  • @import — применяется к классам и полям. Используется для включения активов, CSS и JavaScript.

  • @Path — используется в сочетании с аннотацией @Inject для внедрения актива на основе пути.

  • @Log — применимо к классам и полям. Используется в целях отладки. Может использоваться информация о событиях компонента emit, такая как начало события, конец события и т. Д.

@Property — применимо к полям. Используется для преобразования поля в свойство гобелена.

@Parameter — применимо к полям. Используется для указания поля в качестве параметра компонента.

@Environmental — это применимо к полям. Используется для совместного использования частного поля между различными компонентами.

@import — применяется к классам и полям. Используется для включения активов, CSS и JavaScript.

@Path — используется в сочетании с аннотацией @Inject для внедрения актива на основе пути.

@Log — применимо к классам и полям. Используется в целях отладки. Может использоваться информация о событиях компонента emit, такая как начало события, конец события и т. Д.

IoC аннотация

Используется для добавления объектов в контейнер IoC. Некоторые из полезных аннотаций —

  • @Inject — применимо к полям. Используется для маркировки параметров, которые должны быть введены в контейнер IoC. Он помечает поля, которые должны быть внедрены в компоненты.

  • @Value — применимо к полям. Используется вместе с аннотацией @inject для вставки литерального значения вместо службы (это поведение по умолчанию для аннотации @Inject).

@Inject — применимо к полям. Используется для маркировки параметров, которые должны быть введены в контейнер IoC. Он помечает поля, которые должны быть внедрены в компоненты.

@Value — применимо к полям. Используется вместе с аннотацией @inject для вставки литерального значения вместо службы (это поведение по умолчанию для аннотации @Inject).

Аннотация для классов хранения данных

Он используется для указания специфичной для компонента информации в классе (обычно это модели или классы хранения данных) для компонентов высокого уровня, таких как

  • Сетка (используется для создания расширенных табличных данных, таких как отчет, галерея и т. Д.)

  • BeanEditForm (используется для создания расширенных форм)

  • Hibernate (используется в расширенном доступе к базе данных) и т. Д.

Сетка (используется для создания расширенных табличных данных, таких как отчет, галерея и т. Д.)

BeanEditForm (используется для создания расширенных форм)

Hibernate (используется в расширенном доступе к базе данных) и т. Д.

Эти аннотации объединяются и упаковываются в отдельную банку без какой-либо зависимости от гобелена. Некоторые из аннотаций —

  • @DataType — используется для указания типа данных поля. Компонент Tapestry может использовать эту информацию для создания дизайна или разметки на уровне представления.

  • @Validate — используется для указания правила проверки поля.

@DataType — используется для указания типа данных поля. Компонент Tapestry может использовать эту информацию для создания дизайна или разметки на уровне представления.

@Validate — используется для указания правила проверки поля.

Эти разделения позволяют приложению Tapestry использовать многоуровневый дизайн .

Apache Tapestry — страницы и компоненты

Гобелен приложение представляет собой просто коллекцию гобеленов. Они работают вместе, чтобы сформировать четко определенное веб-приложение. Каждая страница будет иметь соответствующий шаблон XML и ноль, один или несколько компонентов. Страница и Компонент одинаковы, за исключением того, что Страница является корневым компонентом и обычно создается разработчиком приложения.

Компоненты являются дочерними для корневого Pagecomponent . Гобелен имеет множество встроенных компонентов и имеет возможность создать пользовательский компонент.

Компонент страницы

страницы

Как обсуждалось ранее, страницы являются строительными блоками приложения гобелена. Страницы — это простые POJO, расположенные в папке — / src / main / java / «package_path» / pages / . Каждая страница будет иметь соответствующий шаблон XML, и ее расположение по умолчанию — / src / main / resources / «имя_пакета» / pages / .

Здесь вы можете видеть, что структура пути похожа для страницы и шаблона, за исключением того, что шаблон находится в папке ресурсов .

Например, страница регистрации пользователя в приложении Tapestry с именем пакета — com.example.MyFirstApplication будет иметь следующие файлы Page и Template —

  • Java класс

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

  • Шаблон XML

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

Java класс

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

Шаблон XML

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

Давайте создадим простую страницу Hello World . Во-первых, нам нужно создать класс Java по адресу — /src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java ».

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

Затем создайте шаблон XML в —

«/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>

Теперь эта страница доступна по адресу https: // localhost: 8080 / myapp / helloworld . Это простая гобеленовая страница. Tapestry предлагает намного больше возможностей для разработки динамических веб-страниц, которые мы обсудим в следующих главах.

Apache Tapestry — Шаблоны

Давайте рассмотрим XML-шаблон Tapestry в этом разделе. Шаблон XML — это правильно сформированный документ XML. Уровень представления (пользовательского интерфейса) страницы представляет собой шаблон XML. Шаблон XML содержит обычную разметку HTML в дополнение к элементам, указанным ниже:

  • Пространство имен гобеленов
  • расширения
  • элементы
  • Компоненты

Давайте теперь обсудим их подробно.

Пространство имен гобеленов

Пространства имен Tapestry — это не что иное, как пространства имен XML. Пространства имен должны быть определены в корневом элементе шаблона. Он используется для включения компонентов Гобелена и информации, связанной с компонентами, в Шаблон. Наиболее часто используемые пространства имен следующие:

  • xmlns: t = «https://tapestry.apache.org/schema/tapestry_5_4.xsd» — используется для идентификации элементов, компонентов и атрибутов гобелена.

  • xmlns: p = «tapestry: параметр» — используется для передачи произвольных фрагментов кода компонентам.

xmlns: t = «https://tapestry.apache.org/schema/tapestry_5_4.xsd» — используется для идентификации элементов, компонентов и атрибутов гобелена.

xmlns: p = «tapestry: параметр» — используется для передачи произвольных фрагментов кода компонентам.

Пример пространства имен гобеленов следующий:

<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>

расширения

Расширение — это простой и эффективный метод динамического изменения шаблона XML на этапе отображения страницы. Расширение использует синтаксис $ {<name>}. Существует много вариантов выражения расширения в шаблоне XML. Давайте посмотрим некоторые из наиболее часто используемых вариантов —

Расширения недвижимости

Он отображает свойство, определенное в соответствующем классе Page. Это следует за Спецификацией Бина Java для определения свойства в классе Java. Это идет на один шаг дальше, игнорируя случаи для имени свойства. Давайте изменим пример «Hello World», используя расширение свойства. Следующий блок кода — это модифицированный класс Page.

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

Затем измените соответствующий шаблон XML, как показано ниже.

<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>

Здесь мы определили имя как Java Bean Property в классе Page и динамически обработали его в XML-шаблоне, используя расширение $ {name} .

Расширение сообщения

Каждый класс Page может иметь или не иметь связанный файл свойств — «page_name» .properties в папке ресурсов. Файлы свойств представляют собой простые текстовые файлы, имеющие одну пару ключ / значение (сообщение) на строку. Давайте создадим файл свойств для страницы HelloWorld по адресу —

«/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties» и добавьте сообщение «Приветствие».

Greeting = Hello

Приветственное сообщение можно использовать в шаблоне XML как $ {message: приветствие}

<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>

элементы

Гобелен имеет небольшой набор элементов для использования в шаблонах XML. Элементы — это предопределенные теги, определенные в пространстве имен Tapestry —

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

Каждый элемент создан для определенной цели. Доступны следующие элементы гобелена:

<Т: тело>

Когда два компонента вложены, шаблон родительского компонента может обернуться шаблоном дочернего компонента. Элемент <t: body> полезен в этой ситуации. Одно из применений <t: body> находится в макете шаблона.

В общем случае пользовательский интерфейс веб-приложения будет иметь общий верхний колонтитул, нижний колонтитул, меню и т. Д. Эти общие элементы определены в шаблоне XML и называются «Компоновка шаблона» или «Компонент макета». В Tapestry он должен быть создан разработчиком приложения. Компонент Layout — это просто еще один компонент, который размещается в папке компонентов, которая имеет следующий путь — src / main / «java | resources» / «package_name» / components .

Давайте создадим простой компонент макета под названием MyCustomLayout . Код для MyCustomLayout выглядит следующим образом —

<!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; 
}

В классе компонентов MyCustomLayout мы объявили поле заголовка и, используя аннотацию, сделали его обязательным. Теперь измените шаблон HelloWorld.html, чтобы использовать наш пользовательский макет, как показано в блоке кода ниже.

<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>

Здесь мы видим, что шаблон XML не имеет тегов head и body. Tapestry будет собирать эти данные из компонента макета, и <t: body> компонента макета будет заменен шаблоном HelloWorld. После того, как все будет сделано, Tapestry выдаст аналогичную разметку, как указано ниже —

<!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>

Макеты могут быть вложенными. Например, мы можем расширить наш пользовательский макет, включив функции администрирования, и использовать его для раздела администрирования, как указано ниже.

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

<Т: контейнер>

<T: container> является элементом верхнего уровня и включает пространство имен гобелена. Это используется для указания динамического раздела компонента.

Например, компоненту сетки может потребоваться шаблон, чтобы определить, как визуализировать его строки — tr (и столбец td) в таблице HTML.

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

<Т: блок>

<T: block> является заполнителем для динамического раздела в шаблоне. Как правило, блочный элемент не отображается. Только компоненты, определенные в шаблоне, используют блочный элемент. Компоненты будут динамически вводить данные в элемент блока и отображать их. Одним из популярных вариантов использования является AJAX .

Элемент блока обеспечивает точное положение и разметку для динамических данных, которые будут отображены. Каждый элемент блока должен иметь соответствующее свойство Java. Только тогда он может быть динамически обработан. Идентификатор элемента блока должен соответствовать правилам идентификатора переменной Java. Частичный образец приведен ниже.

@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: content> используется для указания фактического содержимого шаблона. В общем, вся разметка считается частью шаблона. Если указано <t: content>, будет рассматриваться только разметка внутри него. Эта функция используется дизайнерами для оформления страницы без компонента макета.

<Т: удалить>

<T: remove> является противоположностью элемента содержимого. Разметка внутри элемента удаления не считается частью шаблона. Он может использоваться только для комментариев на сервере и для целей проектирования.

активы

Активы — это статические файлы ресурсов, такие как таблицы стилей, изображения и файлы JavaScript. Обычно ресурсы помещаются в корневой каталог веб-приложения / src / main / webapp .

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

Tapestry также обрабатывает файлы, хранящиеся в Java Classpath, как активы. Tapestry предоставляет расширенные возможности для включения активов в шаблон с помощью опции расширения.

  • Контекст — Возможность получить доступ к активам в веб-контексте.

Контекст — Возможность получить доступ к активам в веб-контексте.

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

asset — Компоненты обычно хранят свои собственные активы внутри jar-файла вместе с классами Java. Начиная с Tapestry 5.4, стандартным путем для хранения активов в classpath является META-INF / assets . Для библиотек стандартным путем для хранения активов является META-INF / assets / «имя_библиотеки» /. asset: также может вызывать context: extension для получения ресурсов из веб-контекста.

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

Активы могут быть введены на страницу или компонент гобелена с помощью аннотации «Инъекция» и «Путь». Параметром для аннотации Path является относительный путь активов.

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

Параметр Path также может содержать символы Tapestry, определенные в разделе AppModule.java .

Например, мы можем определить символ skin.root со значением context: skins / basic и использовать его, как показано ниже —

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

локализация

Включение ресурсов через гобелен обеспечивает дополнительную функциональность. Одна из таких функций — «Локализация». Гобелен проверит текущую локаль и включит соответствующие ресурсы.

Например, если текущая локаль установлена ​​как de , тогда edit_de.png будет включен вместо edit.png.

CSS

Гобелен имеет встроенную поддержку таблиц стилей. Tapestry будет внедрять tapestry.css как часть основного стека Javascript. Начиная с версии Tapestry 5.4, гобелен также включает фреймворк начальной загрузки . Мы можем включить нашу собственную таблицу стилей, используя обычный тег ссылки. В этом случае таблицы стилей должны находиться в корневом веб-каталоге — / src / main / webapp / .

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

Tapestry предоставляет расширенные возможности для включения таблиц стилей в шаблон с помощью опции расширения, как обсуждалось ранее.

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

Tapestry также предоставляет аннотацию Import для включения таблицы стилей непосредственно в классы Java.

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

Tapestry предоставляет множество опций для управления таблицей стилей через AppModule.java. Некоторые из важных вариантов —

  • Таблицу стилей по умолчанию для гобеленов можно удалить.

Таблицу стилей по умолчанию для гобеленов можно удалить.

@Contribute(MarkupRenderer.class) 

public static void 
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) { 
   configuration.override("InjectDefaultStyleheet", null); 
} 
  • Bootstrap также можно отключить, переопределив его путь.

Bootstrap также можно отключить, переопределив его путь.

configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
  • Включить динамическую минимизацию активов (CSS и JavaScript). Нам также необходимо включить зависимость tapestry-webresources (в pom.xml).

Включить динамическую минимизацию активов (CSS и JavaScript). Нам также необходимо включить зависимость tapestry-webresources (в pom.xml).

@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

Нынешнее поколение веб-приложений в значительной степени зависит от JavaScript, чтобы обеспечить богатый опыт работы на стороне клиента. Гобелен признает это и обеспечивает первоклассную поддержку JavaScript. Поддержка JavaScript глубоко укоренилась в гобеленах и доступна на каждом этапе программирования.

Раньше Tapestry поддерживала только Prototype и Scriptaculous. Но, начиная с версии 5.4, Tapestry полностью переписал слой JavaScript, чтобы сделать его как можно более универсальным и обеспечить первоклассную поддержку JQuery, де-факто библиотеки JavaScript. Кроме того, Tapestry поощряет программирование JavaScript на основе модулей и поддерживает RequireJS, популярную реализацию AMD на стороне клиента (Asynchronous Module Definition — спецификация JavaScript для поддержки модулей и их зависимости асинхронным образом).

Место нахождения

Файлы JavaScript являются активами приложения Tapestry. В соответствии с правилами активов файлы JavaScript размещаются либо в веб-контексте, / sr / main / webapp /, либо в банке под META-INF / assets / location .

Связывание файлов JavaScript

Самый простой способ связать файлы JavaScript в шаблоне XML — напрямую использовать тег script, который является — <script language = «javascript» src = «lative / path / to / js «> </ script> . Но гобелен не рекомендует эти подходы. Tapestry предоставляет несколько опций для связывания файлов JavaScript прямо в самой странице / компоненте. Некоторые из них приведены ниже.

  • @import annotation — @import annotation предоставляет возможность связать несколько библиотек JavaScript с помощью выражения контекста. Его можно применять как к классу Page, так и к его методу. Если применяется к классу Page, он применяется ко всем его методам. Применительно к методу страницы, он применяется только к этому методу, а затем Tapestry связывает библиотеку JavaScript только при вызове метода.

@import annotation — @import annotation предоставляет возможность связать несколько библиотек JavaScript с помощью выражения контекста. Его можно применять как к классу Page, так и к его методу. Если применяется к классу Page, он применяется ко всем его методам. Применительно к методу страницы, он применяется только к этому методу, а затем Tapestry связывает библиотеку JavaScript только при вызове метода.

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

public class MyComponent { 
   // ... 
}
  • Интерфейс JavaScriptSupport — JavaScriptSupport — это интерфейс, определенный гобеленом, и он имеет метод importJavaScriptLibrary для импорта файлов JavaScript. Объект JavScriptSupport может быть легко создан путем простого объявления и аннотирования с помощью аннотации @Environmental.

Интерфейс JavaScriptSupport — JavaScriptSupport — это интерфейс, определенный гобеленом, и он имеет метод importJavaScriptLibrary для импорта файлов JavaScript. Объект JavScriptSupport может быть легко создан путем простого объявления и аннотирования с помощью аннотации @Environmental.

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

@Environmental 
private JavaScriptSupport javaScriptSupport;  
void setupRender() { 
   javaScriptSupport.importJavaScriptLibrary(myEffects); 
}
  • JavaScripSupport может быть внедрен в компонент только с помощью аннотации @Environmental . Для сервисов нам нужно использовать аннотацию @Inject или добавить ее в качестве аргумента в метод конструктора сервисов.

JavaScripSupport может быть внедрен в компонент только с помощью аннотации @Environmental . Для сервисов нам нужно использовать аннотацию @Inject или добавить ее в качестве аргумента в метод конструктора сервисов.

@Inject 
private JavaScriptSupport javaScriptSupport; 
public MyServiceImpl(JavaScriptSupport support) { 
   // ... 
}
  • метод addScript — аналогичен интерфейсу JavaScriptSupport за исключением того, что в нем используется метод addScript, а код напрямую добавляется в выходные данные в нижней части страницы.

метод addScript — аналогичен интерфейсу JavaScriptSupport за исключением того, что в нем используется метод addScript, а код напрямую добавляется в выходные данные в нижней части страницы.

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

Стек JavaScript

Tapestry позволяет объединять группу файлов JavaScript и связанных таблиц стилей и использовать их как единый объект. В настоящее время Tapestry включает в себя стеки на основе Prototype и JQuery.

Разработчик может разработать свои собственные стеки путем реализации интерфейса JavaScriptStack и зарегистрировать его в AppModule.java . После регистрации стек можно импортировать с помощью аннотации @import .

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

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

Apache Tapestry — Компоненты

Как обсуждалось ранее, Компоненты и Страницы одинаковы, за исключением того, что Страница является корневым компонентом и включает в себя один или несколько дочерних компонентов. Компоненты всегда находятся внутри страницы и выполняют почти все динамические функции страницы.

Компоненты Tapestry отображают простые HTML-ссылки на сложные функциональные возможности сетки с помощью интерактивного AJAX . Компонент может включать в себя и другой компонент. Компоненты гобелена состоят из следующих предметов —

  • Класс компонента — основной класс Java компонента.

  • Шаблон XML — шаблон XML похож на шаблон страницы. Класс компонента отображает шаблон как окончательный результат. Некоторые компоненты могут не иметь шаблонов. В этом случае выходные данные будут сгенерированы самим классом компонента с использованием класса MarkupWriter .

  • Тело . Компонент, указанный внутри шаблона страницы, может иметь пользовательскую разметку и называется «Тело компонента». Если шаблон компонента имеет элемент <body /> , то элемент <body /> будет заменен телом компонента. Это похоже на макет, обсужденный ранее в разделе шаблона XML.

  • Рендеринг — Рендеринг — это процесс, который преобразует XML-шаблон и тело компонента в фактический вывод компонента.

  • Параметры — используются для создания связи между компонентом и страницами и, тем самым, передачи данных между ними.

  • События — делегирует функциональность от компонентов своему контейнеру / родительскому элементу (страницам или другому компоненту). Он широко используется в навигации по страницам.

Класс компонента — основной класс Java компонента.

Шаблон XML — шаблон XML похож на шаблон страницы. Класс компонента отображает шаблон как окончательный результат. Некоторые компоненты могут не иметь шаблонов. В этом случае выходные данные будут сгенерированы самим классом компонента с использованием класса MarkupWriter .

Тело . Компонент, указанный внутри шаблона страницы, может иметь пользовательскую разметку и называется «Тело компонента». Если шаблон компонента имеет элемент <body /> , то элемент <body /> будет заменен телом компонента. Это похоже на макет, обсужденный ранее в разделе шаблона XML.

Рендеринг — Рендеринг — это процесс, который преобразует XML-шаблон и тело компонента в фактический вывод компонента.

Параметры — используются для создания связи между компонентом и страницами и, тем самым, передачи данных между ними.

События — делегирует функциональность от компонентов своему контейнеру / родительскому элементу (страницам или другому компоненту). Он широко используется в навигации по страницам.

Rendering

Визуализация компонента выполняется в виде ряда заранее определенных этапов. Каждая фаза в системе компонентов должна иметь соответствующий метод, определенный соглашением или аннотацией в классе компонента.

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

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

Фазы, название метода и аннотации перечислены ниже.

аннотирование Имена методов по умолчанию
@SetupRender setupRender ()
@BeginRender beginRender ()
@BeforeRenderTemplate beforeRenderTemplate ()
@BeforeRenderBody beforeRenderBody ()
@AfterRenderBody afterRenderBody ()
@AfterRenderTemplate afterRenderTemplate ()
@AfterRender afterRender ()
@CleanupRender cleanupRender ()

Каждый этап имеет определенную цель, и они заключаются в следующем —

SetupRender

SetupRender запускает процесс рендеринга. Обычно он устанавливает параметры компонента.

BeginRender

BeginRender начинает рендеринг компонента. Обычно он отображает начальный / начальный тег компонента.

BeforeRenderTemplate

BeforeRenderTemplate используется для украшения шаблона XML, добавляя специальную разметку вокруг шаблона. Он также предоставляет возможность пропустить рендеринг шаблона.

BeforeRenderBody

BeforeRenderTemplate предоставляет возможность пропустить рендеринг элемента тела компонента.

AfterRenderBody

AfterRenderBody будет вызываться после визуализации тела компонента.

AfterRenderTemplate

AfterRenderTemplate будет вызываться после визуализации шаблона компонента.

AfterRender

AfterRender является аналогом BeginRender и обычно отображает закрывающий тег.

CleanupRender

CleanupRender является аналогом SetupRender. Он освобождает / удаляет все объекты, созданные в процессе рендеринга.

Поток фаз рендеринга не только вперед. Он идет туда-сюда между фазами в зависимости от возвращаемого значения фазы.

Например, если метод SetupRender возвращает false, то рендеринг переходит к фазе CleanupRender и наоборот. Чтобы найти четкое представление о потоке между различными фазами, проверьте поток на диаграмме, приведенной ниже.

Список аннотаций

Простой компонент

Давайте создадим простой компонент Hello, который будет иметь выходное сообщение «Hello, Tapestry». Ниже приведен код компонента Hello и его шаблона.

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>

Компонент Hello может быть вызван в шаблоне страницы как —

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

Точно так же компонент может визуализировать тот же вывод, используя MarkupWriter вместо шаблона, как показано ниже.

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>"); 
   } 
}

Давайте изменим шаблон компонента и включим элемент <body />, как показано в блоке кода ниже.

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

Теперь шаблон страницы может включать тело в разметку компонента, как показано ниже.

<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>

Выход будет следующим:

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

параметры

Основное назначение этих параметров — создать связь между полем компонента и свойством / ресурсом страницы. Используя параметры, компонент и соответствующая ему страница связываются и передают данные между собой. Это называется двухсторонним связыванием данных .

Например, компонент текстового поля, используемый для представления возраста на странице управления пользователями, получает свое начальное значение (доступно в базе данных) через параметр. Опять же, после того, как возраст пользователя обновлен и отправлен обратно, компонент отправит обратно обновленный возраст через тот же параметр.

Чтобы создать новый параметр в классе компонентов, объявите поле и укажите аннотацию @Parameter . Этот @Parameter имеет два необязательных аргумента, которые являются —

  • обязательный — делает параметр обязательным. Гобелен выдвигает исключение, если оно не предусмотрено.

  • значение — указывает значение параметра по умолчанию.

обязательный — делает параметр обязательным. Гобелен выдвигает исключение, если оно не предусмотрено.

значение — указывает значение параметра по умолчанию.

Параметр должен быть указан в шаблоне страницы как атрибуты тега компонента. Значение атрибутов должно быть указано с помощью Binding Expression / Expansion, который мы обсуждали в предыдущих главах. Некоторые из расширений, которые мы узнали ранее, —

  • Расширение свойства (prop: «val») — Получить данные из свойства класса страницы.

  • Расширение сообщения (сообщение: «val») — Получить данные из ключа, определенного в файле index.properties.

  • Расширение контекста (context: «val») — Получить данные из папки веб-контекста / src / main / webapp.

  • Расширение актива (asset: «val») — Получить данные из ресурсов, встроенных в jar-файл, / META-INF / assets.

  • Расширение символа (символ: «val») — Получить данные из символов, определенных в AppModule.javafile.

Расширение свойства (prop: «val») — Получить данные из свойства класса страницы.

Расширение сообщения (сообщение: «val») — Получить данные из ключа, определенного в файле index.properties.

Расширение контекста (context: «val») — Получить данные из папки веб-контекста / src / main / webapp.

Расширение актива (asset: «val») — Получить данные из ресурсов, встроенных в jar-файл, / META-INF / assets.

Расширение символа (символ: «val») — Получить данные из символов, определенных в AppModule.javafile.

Гобелен имеет много других полезных дополнений, некоторые из которых приведены ниже —

  • Литеральное расширение (литерал: «val») — буквальная строка.

  • Расширение var (var: «val») — разрешить чтение или обновление переменной рендеринга компонента.

  • Расширение проверки (validate: «val») — специализированная строка, используемая для указания правила проверки объекта. Например, validate: required, minLength = 5.

  • Translate (translate: «val») — используется для указания класса Translator (преобразования клиентской части в представление серверной части) при проверке входных данных.

  • Block (block: «val») — идентификатор элемента блока в шаблоне.

  • Компонент (component: «val») — идентификатор другого компонента в шаблоне.

Литеральное расширение (литерал: «val») — буквальная строка.

Расширение var (var: «val») — разрешить чтение или обновление переменной рендеринга компонента.

Расширение проверки (validate: «val») — специализированная строка, используемая для указания правила проверки объекта. Например, validate: required, minLength = 5.

Translate (translate: «val») — используется для указания класса Translator (преобразования клиентской части в представление серверной части) при проверке входных данных.

Block (block: «val») — идентификатор элемента блока в шаблоне.

Компонент (component: «val») — идентификатор другого компонента в шаблоне.

Все вышеперечисленные расширения доступны только для чтения, за исключением расширения Property и Var. Они используются компонентом для обмена данными со страницей. При использовании раскрытия в качестве значений атрибута не следует использовать $ {…} . Вместо этого просто используйте расширение без символа доллара и скобок.

Компонент, использующий параметр

Давайте создадим новый компонент HelloWithParameter, изменив компонент Hello для динамической визуализации сообщения, добавив параметр имени в класс компонента и изменив соответственно шаблон компонента и шаблон страницы.

  • Создайте новый класс компонента HelloWithParameter.java .

  • Добавьте личное поле и назовите его аннотацией @Parameter . Используйте обязательный аргумент, чтобы сделать его обязательным.

Создайте новый класс компонента HelloWithParameter.java .

Добавьте личное поле и назовите его аннотацией @Parameter . Используйте обязательный аргумент, чтобы сделать его обязательным.

@Parameter(required = true) 
private String name;
  • Добавьте приватное поле, результат с аннотацией @Propery . Свойство результата будет использовано в шаблоне компонента. Шаблон компонента не имеет доступа к полям, аннотированным @Parameter, и может получить доступ только к полям, аннотированным @Property . Переменные, доступные в шаблонах компонентов, называются переменными рендеринга.

Добавьте приватное поле, результат с аннотацией @Propery . Свойство результата будет использовано в шаблоне компонента. Шаблон компонента не имеет доступа к полям, аннотированным @Parameter, и может получить доступ только к полям, аннотированным @Property . Переменные, доступные в шаблонах компонентов, называются переменными рендеринга.

@Property 
 private String result;
  • Добавьте метод RenderBody и скопируйте значение из параметра name в свойство result.

Добавьте метод RenderBody и скопируйте значение из параметра name в свойство result.

@BeginRender 
void initializeValues() { 
   result = name; 
}
  • Добавьте новый шаблон компонента HelloWithParamter.tml и используйте свойство result для отображения сообщения.

Добавьте новый шаблон компонента HelloWithParamter.tml и используйте свойство result для отображения сообщения.

<div> Hello, ${result} </div>
  • Добавьте новое свойство Имя пользователя на тестовой странице (testhello.java).

Добавьте новое свойство Имя пользователя на тестовой странице (testhello.java).

public String getUsername() { 
   return "User1"; 
}
  • Используйте только что созданный компонент в шаблоне страницы и задайте свойство Username в параметре name компонента HelloWithParameter .

Используйте только что созданный компонент в шаблоне страницы и задайте свойство Username в параметре name компонента HelloWithParameter .

<t:helloWithParameter name = "username" /> 

Полный список выглядит следующим образом —

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> 

Результат будет следующим:

<div> Hello, User1 </div>

Расширенный параметр

В предыдущих главах мы анализировали, как создать и использовать простой параметр в пользовательском компоненте. Расширенный параметр также может содержать полную разметку. В этом случае разметка должна быть указана внутри тега компонента, такого как подраздел в шаблоне страницы. Встроенный компонент if имеет разметку для условия успеха и сбоя. Разметка для успеха указывается как тело тега компонента, а разметка для отказа указывается с помощью elseparameter .

Давайте посмотрим, как использовать компонент if . Компонент if имеет два параметра —

  • test — простой параметр на основе свойств

  • Else — Расширенный параметр, используемый для указания альтернативной разметки, если условие не выполнено

test — простой параметр на основе свойств

Else — Расширенный параметр, используемый для указания альтернативной разметки, если условие не выполнено

Tapestry проверит значение свойства test, используя следующую логику, и вернет true или false. Это называется Type Coercion , способ преобразования объекта одного типа в другой тип с тем же содержимым.

  • Если тип данных — String , «True», если он не пустой, а не буквальная строка «False» (без учета регистра).

  • Если тип данных Number , True, если не ноль.

  • Если тип данных — Коллекция , True, если не пустой.

  • Если тип данных — Object , True (если он не нулевой).

Если тип данных — String , «True», если он не пустой, а не буквальная строка «False» (без учета регистра).

Если тип данных Number , True, если не ноль.

Если тип данных — Коллекция , True, если не пустой.

Если тип данных — Object , True (если он не нулевой).

Если условие выполняется, компонент отображает свое тело; в противном случае он отображает тело параметра else.

Полный список выглядит следующим образом —

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>

События компонента / навигация по страницам

Приложение Tapestry представляет собой набор страниц, взаимодействующих друг с другом. До сих пор мы узнали, как создавать отдельные страницы без какой-либо связи между ними. Основным назначением события компонента является обеспечение взаимодействия между страницами (в том числе и внутри страниц) с использованием событий на стороне сервера. Большинство событий компонента происходят из событий на стороне клиента.

Например, когда пользователь щелкает ссылку на странице, Tapestry сама вызывает ту же страницу с целевой информацией вместо вызова целевой страницы и вызывает событие на стороне сервера. Гобеленовая страница будет захватывать событие, обрабатывать информацию о цели и перенаправлять серверную страницу на целевую страницу.

Tapestry следует шаблону разработки Post / Redirect / Get (RPG) для навигации по страницам. В RPG, когда пользователь отправляет запрос, отправив форму, сервер обрабатывает опубликованные данные, но не возвращает ответ напрямую. Вместо этого он выполнит перенаправление на стороне клиента на другую страницу, которая выдаст результат. Шаблон RPG используется для предотвращения дублирования отправки форм с помощью кнопки возврата браузера, кнопки обновления браузера и т. Д. Tapestry предоставляет шаблон RPG, предоставляя следующие два типа запросов.

  • Запрос события компонента — этот тип запроса предназначен для определенного компонента на странице и вызывает события внутри компонента. Этот запрос только перенаправляет и не выводит ответ.

  • Запрос рендеринга — эти типы запросов предназначаются для страницы и направляют ответ обратно клиенту.

Запрос события компонента — этот тип запроса предназначен для определенного компонента на странице и вызывает события внутри компонента. Этот запрос только перенаправляет и не выводит ответ.

Запрос рендеринга — эти типы запросов предназначаются для страницы и направляют ответ обратно клиенту.

Чтобы понять события компонента и навигацию по страницам, нам нужно знать шаблон URL запроса гобелена. Шаблон URL для обоих типов запросов выглядит следующим образом:

  • Запросы событий компонентов

Запросы событий компонентов

/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
  • Запрос рендеринга

Запрос рендеринга

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

Вот некоторые примеры шаблонов URL:

  • Индексную страницу можно запросить по https: // «домен» / «приложение» / index .

  • Если страница указателя доступна в подпапке admin, ее можно запросить по https: // «домен» / «приложение» / admin / index .

  • Если пользователь щелкает компонент ActionLink с идентификатором test на странице индекса, то URL будет https: // «домен» / «приложение» /index.test .

Индексную страницу можно запросить по https: // «домен» / «приложение» / index .

Если страница указателя доступна в подпапке admin, ее можно запросить по https: // «домен» / «приложение» / admin / index .

Если пользователь щелкает компонент ActionLink с идентификатором test на странице индекса, то URL будет https: // «домен» / «приложение» /index.test .

События

По умолчанию Tapestry вызывает события OnPassivate и OnActivate для всех запросов. Для типа запроса события компонента гобелен вызывает дополнительные одно или несколько событий в зависимости от компонента. Компонент ActionLink вызывает событие Action, а компонент Form вызывает несколько событий, таких как Validate, Success и т. Д.,

События могут быть обработаны в классе страницы, используя соответствующий обработчик метода. Обработчик метода создается либо с помощью соглашения об именовании методов, либо с помощью аннотации @OnEvent . Формат соглашения об именах методов: «EventName» из «ComponentId» .

Событие действия компонента ActionLink с тестом id может быть обработано любым из следующих методов:

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

Если имя метода не имеет какого-либо конкретного компонента, метод будет вызван для всех компонентов с совпадающими событиями.

void OnAction() { 
} 

Событие OnPassivate и OnActivate

OnPassivate используется для предоставления контекстной информации для обработчика события OnActivate. В общем, Tapestry предоставляет контекстную информацию, и ее можно использовать в качестве аргумента в обработчике OnActivateevent.

Например, если контекстная информация имеет тип 3 типа int, событие OnActivate можно вызвать как —

void OnActivate(int id) { 
} 

В некоторых случаях контекстная информация может быть недоступна. В этой ситуации мы можем предоставить контекстную информацию обработчику события OnActivate через обработчик события OnPassivate. Тип возвращаемого значения обработчика события OnPassivate должен использоваться в качестве аргумента обработчика события OnActivate.

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

Возвращаемые значения обработчика событий

Tapestry выполняет перенаправление страниц на основе возвращаемых значений обработчика событий. Обработчик события должен возвращать любое из следующих значений.

  • Null Response — Возвращает нулевое значение. Tapestry создаст URL текущей страницы и отправит клиенту в качестве перенаправления.

Null Response — Возвращает нулевое значение. Tapestry создаст URL текущей страницы и отправит клиенту в качестве перенаправления.

public Object onAction() { 
   return null; 
}
  • String Response — Возвращает строковое значение. Tapestry создаст URL-адрес страницы, соответствующий значению, и отправит клиенту в качестве перенаправления.

String Response — Возвращает строковое значение. Tapestry создаст URL-адрес страницы, соответствующий значению, и отправит клиенту в качестве перенаправления.

public String onAction() { 
   return "Index"; 
}
  • Ответ класса — возвращает класс страницы. Tapestry создаст URL-адрес возвращаемого класса страницы и отправит клиенту в качестве перенаправления.

Ответ класса — возвращает класс страницы. Tapestry создаст URL-адрес возвращаемого класса страницы и отправит клиенту в качестве перенаправления.

public Object onAction() { 
   return Index.class 
}
  • Ответ страницы — возвращает поле, помеченное @InjectPage. Tapestry создаст URL внедренной страницы и отправит клиенту в качестве перенаправления.

Ответ страницы — возвращает поле, помеченное @InjectPage. Tapestry создаст URL внедренной страницы и отправит клиенту в качестве перенаправления.

@InjectPage 
private Index index;  

public Object onAction(){ 
   return index; 
}
  • HttpError — Возвращает объект HTTPError. Tapestry выдаст ошибку HTTP на стороне клиента.

HttpError — Возвращает объект HTTPError. Tapestry выдаст ошибку HTTP на стороне клиента.

public Object onAction(){ 
   return new HttpError(302, "The Error message); 
}
  • Ответ ссылки — возвращает экземпляр ссылки напрямую. Tapestry создаст URL из объекта Link и отправит клиенту в качестве перенаправления.

  • Stream Response — возвращает объект StreamResponse . Tapestry отправит поток в ответ непосредственно браузеру клиента. Он используется для генерации отчетов и изображений напрямую и отправки его клиенту.

  • Url Response — Возвращает объект java.net.URL . Гобелен получит соответствующий URL-адрес от объекта и отправит клиенту в качестве перенаправления.

  • Ответ объекта — возвращает любые значения, отличные от указанных выше значений. Гобелен вызовет ошибку.

Ответ ссылки — возвращает экземпляр ссылки напрямую. Tapestry создаст URL из объекта Link и отправит клиенту в качестве перенаправления.

Stream Response — возвращает объект StreamResponse . Tapestry отправит поток в ответ непосредственно браузеру клиента. Он используется для генерации отчетов и изображений напрямую и отправки его клиенту.

Url Response — Возвращает объект java.net.URL . Гобелен получит соответствующий URL-адрес от объекта и отправит клиенту в качестве перенаправления.

Ответ объекта — возвращает любые значения, отличные от указанных выше значений. Гобелен вызовет ошибку.

Контекст события

В общем случае обработчик события может получить контекстную информацию, используя аргументы. Например, если контекстная информация имеет тип 3 типа int, тогда обработчик события будет:

Object onActionFromTest(int id) {  
} 

Tapestry правильно обрабатывает контекстную информацию и предоставляет ее методам через аргументы. Иногда Tapestry может не справиться с этим должным образом из-за сложности программирования. В это время мы можем получить полную контекстную информацию и обработать сами.

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

Apache Tapestry — Встроенные компоненты

В этой главе рассказывается о встроенных компонентах Tapestry на подходящих примерах. Гобелен поддерживает более 65 встроенных компонентов. Вы также можете создавать собственные компоненты. Давайте рассмотрим некоторые известные компоненты в деталях.

Если компонент

Компонент if используется для условной визуализации блока. Условие проверяется тестовым параметром.

Создайте страницу IfSample.java, как показано ниже —

package com.example.MyFirstApplication.pages;  

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

Теперь создайте соответствующий файл шаблона следующим образом:

<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>

Запрос страницы отобразит результат, как показано ниже.

Результат — http: // localhost: 8080 / MyFirstApplication / ifsample

Если компонент результат

Если и делегировать компонент

Компонент Тогда — просто противоположность компонента if, который обсуждался выше. Хотя компонент делегата не выполняет никакого рендеринга сам по себе. Вместо этого он обычно делегирует разметку для блокирования элемента. Если и если компоненты не могут использовать делегировать и блокировать для условного обмена динамического содержимого.

Создайте страницу Unless.java следующим образом.

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; 
      } 
   }   
} 

Теперь создайте соответствующий файл шаблона следующим образом:

<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>

Запрос страницы отобразит результат, как показано ниже.

Результат — http: // localhost: 8080 / MyFirstApplication /, если

Компонент делегата

Петля компонент

Компонент цикла является основным компонентом для циклического перемещения по элементам коллекции и визуализации тела для каждого значения / итерации.

Создайте страницу Loop, как показано ниже —

Loop.java

package com.example.MyFirstApplication.pages;  

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

Затем создайте соответствующий шаблон 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>

Компонент Loop имеет следующие два параметра —

  • источник — источник коллекции. 1… 5 — расширение свойства, используемое для создания массива с указанным диапазоном.

  • var — переменная рендеринга. Используется для отображения текущего значения в теле шаблона.

источник — источник коллекции. 1… 5 — расширение свойства, используемое для создания массива с указанным диапазоном.

var — переменная рендеринга. Используется для отображения текущего значения в теле шаблона.

Запрос страницы выдаст результат, как показано ниже —

Петля компонент

Компонент PageLink

Компонент PageLink используется для связи страницы с одной страницы на другую. Создайте тестовую страницу PageLink, как показано ниже — PageLink.java .

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

Затем создайте соответствующий файл шаблона, как показано ниже —

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>

Компонент PageLink имеет параметр страницы, который должен ссылаться на целевую страницу гобелена.

Результат — http: // localhost: 8080 / myFirstApplication / pagelink

Ссылка на страницу

Компонент EventLink

Компонент EventLink отправляет имя события и соответствующий параметр через URL. Создайте класс страницы EventsLink, как показано ниже.

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; 
   }   
}

Затем создайте соответствующий файл шаблона «EventsLink» следующим образом:

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 имеет следующие два параметра —

  • Событие — имя события, которое должно быть запущено в компоненте EventLink. По умолчанию он указывает на идентификатор компонента.

  • Контекст — это необязательный параметр. Он определяет контекст для ссылки.

Событие — имя события, которое должно быть запущено в компоненте EventLink. По умолчанию он указывает на идентификатор компонента.

Контекст — это необязательный параметр. Он определяет контекст для ссылки.

Результат — http: // localhost: 8080 / myFirstApplication / EventsLink

Ссылка на событие

После нажатия значения счетчика на странице отобразится имя события в URL-адресе, как показано на следующем выходном снимке экрана.

Событие Ссылка Результат

Компонент ActionLink

Компонент ActionLink аналогичен компоненту EventLink, но он отправляет только идентификатор целевого компонента. Имя события по умолчанию — действие.

Создайте страницу «ActivationLinks.java», как показано ниже,

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; 
   } 
} 

Теперь создайте соответствующий файл шаблона, как показано ниже —

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> 

Здесь метод OnActionFromSub будет вызываться при щелчке компонента ActionLink.

Результат — http: // localhost: 8080 / myFirstApplication / ActivationsLink

Действие Ссылка

Компонент оповещения

Диалоговое окно предупреждения в основном используется для выдачи предупреждающего сообщения пользователям. Например, если для поля ввода требуется обязательный текст, но пользователь не вводит никаких данных, в качестве части проверки вы можете использовать окно предупреждения для выдачи предупреждающего сообщения.

Создайте страницу «Оповещения», как показано в следующей программе.

Alerts.java

package com.example.MyFirstApplication.pages;  

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

Затем создайте соответствующий файл шаблона следующим образом:

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>

Оповещение имеет три уровня серьезности, которые:

  • Информация
  • предостерегать
  • ошибка

Приведенный выше шаблон создан с использованием информационного оповещения. Это определяется как alert-info . Вы можете создавать другие уровни серьезности в зависимости от необходимости.

Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / Alerts

Оповещения

Формы и компоненты проверки

Компонент формы используется для создания формы на странице гобелена для пользовательского ввода. Форма может содержать текстовые поля, поля даты, поля флажков, опции выбора, кнопку отправки и многое другое.

В этой главе подробно описываются некоторые известные компоненты формы.

Флажок Компонент

Компонент Checkbox используется для выбора между двумя взаимоисключающими опциями. Создайте страницу, используя флажок, как показано ниже —

Checkbox.java

package com.example.MyFirstApplication.pages;  

import org.apache.tapestry5.annotations.Property;  

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

Теперь создайте соответствующий шаблон Checkbox.tml, как показано ниже —

<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> 

Здесь идентификатор параметра флажка соответствует соответствующему логическому значению.

Результат — после запроса страницы, http: // localhost: 8080 / myFirstApplication /, флажок выдаст следующий результат.

флажок

Компонент TextField

Компонент TextField позволяет пользователю редактировать одну строку текста. Создайте текст страницы, как показано ниже.

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; 
}

Затем создайте соответствующий шаблон, как показано ниже — 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>

Здесь текстовая страница содержит свойство с именами fname и lname . Идентификаторы компонентов доступны через свойства.

Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / Текст

Текстовое поле

Компонент PasswordField

PasswordField — это специальное текстовое поле для ввода пароля. Создайте пароль страницы, как показано ниже —

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; 
}

Теперь создайте соответствующий файл шаблона, как показано ниже —

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> 

Здесь компонент PasswordField имеет параметр id, который указывает на свойство pwd . Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / Пароль

Поле пароля

Компонент TextArea

Компонент TextArea — это многострочный элемент управления вводом текста. Создайте страницу TxtArea, как показано ниже.

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;  
}

Затем создайте соответствующий файл шаблона, как показано ниже.

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>

Здесь идентификатор параметра компонента TextArea указывает на свойство «str». Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / TxtArea **

Компонент TextArea

Выберите компонент

Компонент Select содержит раскрывающийся список вариантов. Создайте страницу SelectOption, как показано ниже.

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 
   } 
}

Затем создайте соответствующий шаблон следующим образом —

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>

Здесь компонент Select имеет два параметра:

  • Тип — Тип свойства — перечисление.

  • Id — Id указывает на свойство гобелена «color1».

Тип — Тип свойства — перечисление.

Id — Id указывает на свойство гобелена «color1».

Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / SelectOption

Выберите компонент

Радиогруппа

Компонент RadioGroup предоставляет группу контейнеров для компонентов Radio. Компоненты Radio и RadioGroup работают вместе, чтобы обновить свойство объекта. Этот компонент должен обернуться вокруг других компонентов радио. Создайте новую страницу «Radiobutton.java», как показано ниже —

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; 
}

Затем создайте соответствующий файл шаблона, как показано ниже —

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>

Здесь идентификатор компонента RadioGroup связывается со свойством «значение». Запрос страницы даст следующий результат.

HTTP: // локальный: 8080 / myFirstApplication / RadioButton

Радио Группа

Отправить компонент

Когда пользователь нажимает кнопку отправки, форма отправляется на адрес, указанный в настройке действия тега. Создайте страницу SubmitComponent, как показано ниже.

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

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

Теперь создайте соответствующий файл шаблона, как показано ниже.

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>

Здесь компонент Submit отправляет значение на страницу индекса. Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / SubmitComponent

Отправить компонент

Проверка формы

Проверка формы обычно происходит на сервере после того, как клиент ввел все необходимые данные и затем отправил форму. Если данные, введенные клиентом, были неправильными или просто отсутствовали, сервер должен был бы отправить все данные обратно клиенту и запросить повторную отправку формы с правильной информацией.

Давайте рассмотрим следующий простой пример, чтобы понять процесс проверки.

Создайте страницу проверки, как показано ниже.

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; 
}

Теперь создайте соответствующий файл шаблона, как показано ниже.

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>

Форма проверки имеет следующие важные параметры —

  • Макс — определяет максимальное значение, например, = «максимальное значение, 20».

  • MaxDate — определяет maxDate, например, = «максимальная дата, 06.09.2013». Точно так же вы можете назначить MinDate.

  • MaxLength — maxLength для eg = «максимальная длина, 80».

  • Мин — минимум.

  • MinLength — минимальная длина, например, = «minmum length, 2».

  • Электронная почта — проверка электронной почты, в которой используется стандартное регулярное выражение электронной почты ^ ^ w [._ \ w] * \ w @ \ w [-._ \ w] * \ w \. \ W2,6 $ или нет.

Макс — определяет максимальное значение, например, = «максимальное значение, 20».

MaxDate — определяет maxDate, например, = «максимальная дата, 06.09.2013». Точно так же вы можете назначить MinDate.

MaxLength — maxLength для eg = «максимальная длина, 80».

Мин — минимум.

MinLength — минимальная длина, например, = «minmum length, 2».

Электронная почта — проверка электронной почты, в которой используется стандартное регулярное выражение электронной почты ^ ^ w [._ \ w] * \ w @ \ w [-._ \ w] * \ w \. \ W2,6 $ или нет.

Запрос страницы даст следующий результат —

HTTP: // локальный: 8080 / myFirstApplication / Validate

Проверка формы

Apache Tapestry — Компонент Ajax

AJAX расшифровывается как асинхронный JavaScript и XML . Это методика создания более качественных, быстрых и интерактивных веб-приложений с помощью XML, JSON, HTML, CSS и JavaScript . AJAX позволяет отправлять и получать данные асинхронно, без перезагрузки веб-страницы, поэтому это быстро.

Компонент зоны

Компонент зоны используется для предоставления содержимого (разметки), а также положения самого содержимого. Тело компонента зоны используется внутри Tapestry для генерации контента. Как только динамический контент будет сгенерирован, Tapestry отправит его клиенту, отобразит данные в нужном месте, запустит и анимирует HTML, чтобы привлечь внимание пользователя.

Этот компонент Zone используется вместе с компонентом EventLink. EventLink имеет возможность привязать его к определенной зоне, используя атрибуты t: zone . Как только зона сконфигурирована в EventLink, нажатие на EventLink вызовет обновление зоны. Кроме того, события EventLink (refreshZone) могут использоваться для управления генерацией динамических данных.

Простой пример AJAX следующий:

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(); 
   } 
} 

Результат будет показан по адресу: http: // localhost: 8080 / MyFirstApplication / AjaxZone

Часовой пояс Аякс

Apache Tapestry — Hibernate

В этой главе мы обсудим интеграцию компонентов BeanEditForm и Grid с Hibernate. Hibernate интегрируется в гобелен через модуль Hibernate. Чтобы включить модуль hibernate, добавьте зависимость tapestry-hibernate и, необязательно, hsqldb в файл pom.xml . Теперь настройте hibernate с помощью файла hibernate.cfg.xml, расположенного в корне папки ресурсов.

pom.xml (частично)

<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> 

Давайте посмотрим, как создать страницу добавления сотрудников с помощью компонента BeanEditForm и страницу списка сотрудников с помощью компонента Grid. Слой персистентности обрабатывается модулем Hibernate.

Создайте класс сотрудника и украсьте его аннотацией @Entity. Затем добавьте аннотацию проверки для соответствующих полей и аннотацию, связанную с hibernate @Id и @GeneratedValue для поля id. Также создайте пол как тип enum.

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 
}

Создайте страницу со списком сотрудников ListEmployee.java в новой папке employee под страницами и соответствующий файл шаблона ListEmployee.tml в папке / src / main / resources / pages / employee . Tapestry предоставляет короткий URL для подпапок, удаляя повторяющиеся данные.

Например, страница ListEmployee может быть открыта по обычному URL — (/ employee / listemployee) и по короткому URL — (/ employee / list).

Добавьте сеанс Hibernate на страницу списка с помощью аннотации @Inject. Определите свойство getEmployees на странице списка и заполните его сотрудниками, используя внедренный объект сеанса. Заполните код для класса сотрудников, как показано ниже.

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(); 
   } 
} 

Создайте файл шаблона для класса ListEmployee. Шаблон будет состоять из двух основных компонентов:

  • PageLink — Создать страницу ссылки на сотрудников.

  • Сетка — используется для отображения данных о сотруднике. Компонент сетки имеет исходные атрибуты для добавления списка сотрудников и включает атрибуты для включения отображаемых полей.

PageLink — Создать страницу ссылки на сотрудников.

Сетка — используется для отображения данных о сотруднике. Компонент сетки имеет исходные атрибуты для добавления списка сотрудников и включает атрибуты для включения отображаемых полей.

ListEmployee.tml (список всех сотрудников)

<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>

Создайте файл шаблона создания сотрудника и включите компонент BeanEditForm. Компонент имеет следующие атрибуты —

  • объект — включает в себя источник.

  • reorder — определяет порядок отображения полей.

  • submitlabel — Сообщение кнопки отправки формы

объект — включает в себя источник.

reorder — определяет порядок отображения полей.

submitlabel — Сообщение кнопки отправки формы

Полное кодирование выглядит следующим образом:

<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> 

Создайте класс создания сотрудника и включите сеанс, свойство сотрудника, страницу списка (навигационную ссылку) и определите событие OnSuccess (место для обновления данных) компонента. Данные сеанса сохраняются в базе данных, используя сеанс гибернации.

Полное кодирование выглядит следующим образом:

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; 
   } 
}

Добавьте файл CreateEmployee.properties и включите сообщение, которое будет использоваться в проверках формы. Полный код выглядит следующим образом —

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

Снимок экрана со страницей создания сотрудника и страницей списка приведен ниже —

Создание сотрудника

Страница создания

Apache Tapestry — Хранение

Каждое веб-приложение должно иметь некоторый способ хранения определенных пользовательских данных, таких как объект пользователя, пользовательские предпочтения и т. Д. Например, в приложении корзины покупок выбранные пользователем товары / товары должны сохраняться во временном контейнере (корзине) до тех пор, пока пользователь не отдает предпочтение купить продукты. Мы можем сохранить элементы в базе данных, но это будет слишком дорого, поскольку все пользователи не собираются покупать выбранные элементы. Итак, нам нужно временное устройство для хранения / сохранения предметов. Apache Tapestry Предоставляет два способа сохранения данных, и они —

  • Данные персистентной страницы
  • Хранилище сессий

У обоих есть свои преимущества и недостатки. Мы проверим это в следующих разделах.

Данные персистентной страницы

Данные персистентности страницы — это простая концепция для сохранения данных на одной странице между запросами, которая также называется персистентностью на уровне страницы . Это можно сделать с помощью аннотации @Persist .

@Persist 
public int age; 

Как только поле аннотируется @Persist, значение поля будет сохраняться в запросе, и если значение будет изменено во время запроса, оно будет отражено при следующем обращении к нему. Apache Tapestry предлагает пять типов стратегий для реализации концепции @Persist. Они заключаются в следующем —

  • Стратегия сеанса — данные сохраняются с использованием сеанса, и это стратегия по умолчанию.

  • Стратегия Flash — данные также сохраняются с использованием Session, но они очень недолговечны. Данные будут доступны только в одном последующем запросе.

Стратегия сеанса — данные сохраняются с использованием сеанса, и это стратегия по умолчанию.

Стратегия Flash — данные также сохраняются с использованием Session, но они очень недолговечны. Данные будут доступны только в одном последующем запросе.

@Persist(PersistenceConstants.FLASH) 
private int age;
  • Стратегия клиента — данные сохраняются на стороне клиента, такие как строка запроса URL, скрытое поле в форме и т. Д.

Стратегия клиента — данные сохраняются на стороне клиента, такие как строка запроса URL, скрытое поле в форме и т. Д.

@Persist(PersistenceConstants.FLASH) 
private int age; 
  • Стратегия Hibernate Entity — данные сохраняются с использованием модуля Hibernate в качестве Entity. Сущность будет сохранена в Hibernate, а ее ссылка (имя класса Java и его первичный ключ) будет сохранена как токен в HttpSession . Объект будет восстановлен с использованием токена, доступного в HttpSession.

Стратегия Hibernate Entity — данные сохраняются с использованием модуля Hibernate в качестве Entity. Сущность будет сохранена в Hibernate, а ее ссылка (имя класса Java и его первичный ключ) будет сохранена как токен в HttpSession . Объект будет восстановлен с использованием токена, доступного в HttpSession.

@Persist(HibernatePersistenceConstants.ENTITY) 
private Category category;
  • Стратегия сущности JPA — данные сохраняются с использованием модуля JPA. Он сможет хранить только Entity.

Стратегия сущности JPA — данные сохраняются с использованием модуля JPA. Он сможет хранить только Entity.

@Persist(JpaPersistenceConstants.ENTITY) 
private User user; 

Хранилище сессий

Хранилище сеансов — это продвинутая концепция, используемая для хранения данных, которые должны быть доступны на разных страницах, таких как данные в мастере многостраничных данных, информация о пользователе и т. Д. Хранилище сеансов предоставляет два варианта: один для хранения сложного объекта, а другой для хранения простых значений.

  • Session Store Object — Используется для хранения сложного объекта.

  • Атрибуты сеанса — используются для хранения простых значений.

Session Store Object — Используется для хранения сложного объекта.

Атрибуты сеанса — используются для хранения простых значений.

Объект хранилища сеансов (SSO)

Единый вход может быть создан с помощью аннотации @SessionStore . SSO будет хранить объект, используя тип объекта. Например, объект Cart будет сохранен с использованием имени класса Cart в качестве токена. Таким образом, любой сложный объект может быть сохранен в приложении один раз (по одному на пользователя).

public class MySSOPage { 
   @SessionState 
   private ShoppingCart cart; 
}

SSO — это специализированное хранилище, и его следует использовать для хранения только сложных / специальных объектов. Простые типы данных также могут храниться с использованием единого входа, но хранение простых типов данных, таких как String, позволяет хранить в приложении только одно значение «String». Использование одного значения «String» в приложении просто невозможно. Вы можете использовать простые типы данных, так как Apache Tapestry предоставляет атрибуты сеанса.

Атрибуты сеанса

Атрибуты сеанса позволяют хранить данные по имени, а не по типу.

public class MyPage { 
   @SessionAttribute  
   private String loggedInUsername; 
}

По умолчанию атрибуты сеанса используют имя поля для ссылки на данные в сеансе. Мы можем изменить имя ссылки по параметру аннотации, как показано ниже —

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

Одна из основных проблем использования имени в качестве ссылки на сессию заключается в том, что мы можем случайно использовать одно и то же имя в нескольких классах / страницах. В этом случае сохраненные данные могут быть неожиданно изменены. Чтобы решить эту проблему, будет лучше использовать имя вместе с именем класса / страницы и именем пакета, например com.myapp.pages.register.email , где com.myapp.pages — это имя пакета, register — это страница / класс. имя и, наконец, адрес электронной почты является переменной (для хранения) имя.

Apache Tapestry — Расширенные возможности

В этой главе мы подробно обсудим несколько расширенных функций Apache Tapestry.

Инверсия контроля

Tapestry предоставляет встроенную библиотеку Inversion of Control. Гобелен глубоко интегрирован в IoC и использует IoC для всех своих функций. Конфигурация IoC на основе Tapestry основана на самой Java, а не на XML, как и многие другие контейнеры IoC. Модули на основе Tapestry IoC упакованы в файл JAR и просто помещены в путь к классам с нулевой конфигурацией. Использование гобеленов IoC основано на легкости, что означает —

  • Небольшие интерфейсы двух или трех методов.

  • Небольшие методы с двумя или тремя параметрами.

  • Анонимное общение через события, а не явные вызовы методов.

Небольшие интерфейсы двух или трех методов.

Небольшие методы с двумя или тремя параметрами.

Анонимное общение через события, а не явные вызовы методов.

Модули

Модуль — это способ расширить функциональность приложения Tapestry. Гобелен имеет как встроенные модули, так и большое количество сторонних модулей. Hibernate — один из самых полезных и очень полезных модулей, предоставляемых Tapestry. Он также имеет модули, интегрирующие JMX, JPA, Spring Framework, JSR 303 Bean Validation, JSON и т. Д. Некоторые из известных сторонних модулей:

  • Гобелен-Cayenne
  • Tapestry5-GoogleAnalytics
  • Банда гобеленов 5 — Tapestry5-HighCharts
  • Банда гобеленов 5 — Tapestry5-jqPlot
  • Банда гобеленов 5 — Гобелен5-Jquery
  • Банда гобеленов 5 — Tapestry5-Jquery-мобильный
  • Банда гобеленов 5 — Гобелен5-портлет

Исключения во время выполнения

Одна из лучших функций гобелена — подробный отчет об ошибках . Tapestry помогает разработчику, предоставляя самые современные отчеты об исключениях. Отчет об исключении гобеленов представляет собой простой HTML с подробной информацией. Любой может легко понять отчет. Гобелен показывает ошибку в HTML, а также сохраняет исключение в виде обычного текста с указанием даты и времени возникновения исключения. Это поможет разработчику проверить исключение и в производственной среде. Разработчик может быть уверен в исправлении любых проблем, таких как сломанные шаблоны, неожиданные значения NULL, непревзойденный запрос и т. Д.,

Живой класс и перезагрузка шаблона

Tapestry перезагрузит шаблоны и классы автоматически при изменении. Эта функция позволяет немедленно отражать изменения приложения без прохождения цикла сборки и тестирования. Также эта функция значительно повышает производительность разработки приложений.

Предположим, что корневым пакетом приложения является org.example.myfirstapp . Затем классы в следующих путях сканируются для повторной загрузки.

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

Перезагрузку живого класса можно отключить, установив для рабочего режима значение true в AppModule.java .

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

Модульное тестирование

Модульное тестирование — это метод тестирования отдельных страниц и компонентов. Гобелен предоставляет легкие варианты для модульного тестирования страниц и компонентов.

Модульное тестирование страницы: Tapestry предоставляет класс PageTester для тестирования приложения. Это действует как браузер и контейнер сервлета. Он отображает страницу без браузера на самой стороне сервера, и итоговый документ можно проверить на правильность отображения. Рассмотрим простую страницу Hello , которая отображает hello, а hello-текст заключен в элемент html с идентификатором hello_id . Чтобы протестировать эту функцию, мы можем использовать PageTester, как показано ниже —

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 также предоставляет возможность включать контекстную информацию, отправку форм, навигацию по ссылкам и т. Д. В дополнение к визуализации страницы.

Комплексное тестирование

Интегрированное тестирование помогает тестировать приложение как модуль, а не проверять отдельные страницы, как в модульном тестировании. В интегрированном тестировании несколько модулей могут тестироваться вместе как единое целое. Tapestry предоставляет небольшую библиотеку Tapestry Test Utilities для комплексного тестирования. Эта библиотека интегрируется с инструментом тестирования Selenium для выполнения тестирования. Библиотека предоставляет базовый класс SeleniumTestCase , который запускает и управляет сервером Selenium, клиентом Selenium и Jetty Instance.

Один из примеров комплексного тестирования выглядит следующим образом:

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"); 
   } 
}

Панель разработки

Панель инструментов разработки — это страница по умолчанию, которая используется для выявления / устранения проблем в вашем приложении. Доступ к панели инструментов осуществляется по URL-адресу http: // localhost: 8080 / myfirstapp / core / t5dashboard . На панели инструментов отображаются все страницы, службы и библиотеки компонентов, доступные в приложении.

Сжатие ответа

Tapestry автоматически сжимает ответ, используя сжатие GZIP, и передает его клиенту. Эта функция уменьшит сетевой трафик и поможет быстрее доставить страницу. Сжатие можно настроить с помощью символа tapestry.min-gzip-size в AppModule.java. Значение по умолчанию составляет 100 байт. Гобелен сжимает ответ, как только размер ответа пересекает 100 байтов.

Безопасность

Tapestry предоставляет множество возможностей для защиты приложения от известных уязвимостей в веб-приложении. Некоторые из этих вариантов перечислены ниже —

  • HTTPS — страницы гобеленов могут быть помечены @Secure, чтобы сделать их защищенной и доступными только по протоколу https .

  • Контроль доступа к странице — управление страницей, доступ к которой имеет только определенный пользователь.

  • Страница, занесенная в белый список — страницы гобеленов могут быть аннотированы @WhitelistAccessOnly, чтобы сделать их доступными только через локальный хост .

  • Безопасность активов — Под гобеленом доступны только определенные типы файлов. Другие могут быть доступны только при наличии хеша MD5 файла.

  • Дата сериализованного объекта — Tapestry интегрирует HMAC в сериализованные данные объекта Java и отправляет их клиенту, чтобы избежать фальсификации сообщений.

  • Подделка межсайтовых запросов — Tapestry предоставляет сторонний модуль, называемый tapestry-csrf-protection, для предотвращения любых CSRF-атак.

  • Интеграция структуры безопасности — Tapestry не блокируется в одной реализации аутентификации / авторизации. Гобелен может быть интегрирован с любой популярной платформой аутентификации.

HTTPS — страницы гобеленов могут быть помечены @Secure, чтобы сделать их защищенной и доступными только по протоколу https .

Контроль доступа к странице — управление страницей, доступ к которой имеет только определенный пользователь.

Страница, занесенная в белый список — страницы гобеленов могут быть аннотированы @WhitelistAccessOnly, чтобы сделать их доступными только через локальный хост .

Безопасность активов — Под гобеленом доступны только определенные типы файлов. Другие могут быть доступны только при наличии хеша MD5 файла.

Дата сериализованного объекта — Tapestry интегрирует HMAC в сериализованные данные объекта Java и отправляет их клиенту, чтобы избежать фальсификации сообщений.

Подделка межсайтовых запросов — Tapestry предоставляет сторонний модуль, называемый tapestry-csrf-protection, для предотвращения любых CSRF-атак.

Интеграция структуры безопасности — Tapestry не блокируется в одной реализации аутентификации / авторизации. Гобелен может быть интегрирован с любой популярной платформой аутентификации.

логирование

Tapestry предоставляет обширную поддержку для регистрации, автоматической записи прогресса приложения во время его работы. Tapestry использует библиотеку журналов Java де-факто, SLF4J . Аннотация @Log может быть в любом компонентном методе для создания входа и выхода метода, а также возможного исключения. Кроме того, предоставленный Tapestry объект logger может быть внедрен в любой компонент с помощью аннотации @Inject, как показано ниже —

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

Наконец, теперь мы можем сказать, что Apache Tapestry предлагает лучшие способы создания кратких, масштабируемых, поддерживаемых, надежных приложений с поддержкой Ajax. Гобелен может быть интегрирован с любым сторонним Java-приложением. Это также может помочь в создании большого веб-приложения, поскольку оно довольно простое и быстрое.