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
Давайте обсудим последовательность действий, выполняемых при запросе страницы гобелена.
Шаг 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 () .
Шаг 3 — HttpServletRequestHandler сохраняет запрос и ответ в RequestGlobals . Он также упаковывает запрос и ответ в качестве объекта запроса и ответа и отправляет его в RequestHandler.
Шаг 4 — RequestHandler — это абстракция поверх HttpServletRequest Servlet API. Некоторые из характерных особенностей гобелена сделаны в разделе RequestHandler . Функцию гобелена можно расширить, написав фильтр в RequestHandler. RequestHandler предоставляет несколько встроенных фильтров, которые включают в себя:
-
CheckForUpdates Filter — отвечает за перезагрузку класса в реальном времени. Этот фильтр проверяет классы Java на наличие изменений и обновляет приложение по мере необходимости.
-
Фильтр локализации — определяет местоположение пользователя и обеспечивает поддержку локализации для приложения.
-
Фильтр StaticFiles — определяет статический запрос и прерывает процесс. Как только процесс прерван, сервлет Java берет на себя управление и обрабатывает запрос.
-
Фильтр ошибок — ловит необнаруженное исключение и представляет страницу отчета об исключении.
CheckForUpdates Filter — отвечает за перезагрузку класса в реальном времени. Этот фильтр проверяет классы Java на наличие изменений и обновляет приложение по мере необходимости.
Фильтр локализации — определяет местоположение пользователя и обеспечивает поддержку локализации для приложения.
Фильтр StaticFiles — определяет статический запрос и прерывает процесс. Как только процесс прерван, сервлет Java берет на себя управление и обрабатывает запрос.
Фильтр ошибок — ловит необнаруженное исключение и представляет страницу отчета об исключении.
RequestHandler также изменяет и сохраняет запрос и ответ в RequestQlobals и вызывает службу MasterDispatcher.
Шаг 5 — MasterDispatcher отвечает за рендеринг страницы, вызывая несколько диспетчеров определенного порядка. Четыре главных диспетчера, вызываемые 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 архетип)
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 нажмите кнопку «Далее» и еще раз нажмите кнопку «Далее».
После этого вы получите экран, где вы должны выбрать опцию конфигурации. Как только он будет настроен, вы получите следующий экран.
Шаг 2: Конфигурация каталога
После того, как первый шаг сделан, вы должны нажать Add Remote Catalog . Затем добавьте следующие изменения, как показано на следующем снимке экрана.
Теперь добавлен каталог гобеленов Apache. Затем выберите опцию фильтра org.apache.tapestry quickstart 5.4.1, как показано ниже.
Затем нажмите Next, и появится следующий экран.
Шаг 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: 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 **
Выберите компонент
Компонент 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-приложением. Это также может помочь в создании большого веб-приложения, поскольку оно довольно простое и быстрое.