Apache Tapestry - Szybki przewodnik
Apache Tapestry to platforma internetowa typu open source napisana w języku Java. To jestcomponent based web framework. Komponenty Tapestry to klasy Java. Nie są one dziedziczone ani z klasy bazowej specyficznej dla frameworka, ani z implementacji interfejsu i są po prostu zwykłymi POJO (zwykłe stare obiekty Java).
Ważną cechą języka Java używanego przez tapestry jest Annotation. Strony internetowe Tapestry są konstruowane przy użyciu jednego lub więcej komponentów, z których każdy ma szablon oparty na XML i klasę komponentów ozdobioną wieloma adnotacjami Tapestry. Tapestry może stworzyć wszystko, od małej, jednostronicowej aplikacji internetowej po ogromną, składającą się z setek stron.
Korzyści z Tapestry
Niektóre z korzyści zapewnianych przez gobelin to:
- Wysoce skalowalne aplikacje internetowe.
- Adaptacyjne API.
- Szybki i dojrzały framework.
- Trwałe zarządzanie stanem pamięci masowej.
- Wbudowana inwersja kontroli.
Cechy tkaniny Tapestry
Tapestry ma następujące funkcje -
- Przeładowywanie zajęć na żywo
- Jasne i szczegółowe raportowanie wyjątków
- Struktura statyczna, zachowania dynamiczne.
- Szerokie wykorzystanie zwykłych starych obiektów Java (POJO)
- Mniej koduj, więcej dostarczaj.
Dlaczego Tapestry?
Już Java ma wiele frameworków internetowych, takich jak JSP, Struts itp. Po co więc nam inny framework? Większość dzisiejszych frameworków internetowych Java jest złożona i wymaga stromej krzywej uczenia się. Są staroświeckie i wymagają cyklu kompilacji, testowania i wdrażania dla każdej aktualizacji.
Z drugiej strony Tapestry zapewnia nowoczesne podejście do programowania aplikacji internetowych, udostępniając live class reloading. Podczas gdy inne frameworki wprowadzają wiele interfejsów, klas abstrakcyjnych i bazowych, Tapestry wprowadza tylko niewielki zestaw adnotacji i nadal zapewnia możliwość pisania dużych aplikacji z bogatą obsługą AJAX.
Tapestry stara się maksymalnie wykorzystać dostępne funkcje Javy. Na przykład wszystkie strony Tapestry to po prostu POJO. Nie wymusza żadnych niestandardowych interfejsów ani klas bazowych do napisania aplikacji. Zamiast tego używa adnotacji (lekkiej opcji rozszerzającej funkcjonalność klasy Java) do udostępniania funkcji. Opiera się na sprawdzonych w bojuJava Servlet APIi jest implementowany jako filtr serwletów. Zapewnia nowy wymiar aplikacji internetowej, a programowanie jest dość proste, elastyczne, zrozumiałe i solidne.
Przepływ pracy
Omówmy kolejność działań, które mają miejsce, gdy żądana jest strona z gobelinem.
Step 1 - The Java Servletotrzymuje żądanie strony. Ten serwlet Java jest skonfigurowany w taki sposób, że przychodzące żądanie będzie przekazywane do tapestry. Konfiguracja odbywa się wweb.xmljak określono w następującym programie. Tag Filter and Filter Mapping przekierowuje wszystkie żądania do Tapestry Filter .
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>My Tapestry Application</display-name>
<context-param>
<param-name>tapestry.app-package</param-name>
<param-value>org.example.myapp</param-value>
</context-param>
<filter>
<filter-name>app</filter-name>
<filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>app</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Step 2 - The Tapestry Filter wywołuje HttpServletRequestHandler Serwis według jego Service() metoda.
Step 3 - HttpServletRequestHandler przechowuje żądanie i odpowiedź w formacie RequestGlobals. Również opakowuje żądanie i odpowiedź jako obiekt Request and Response i wysyła je do RequestHandler.
Step 4 - The RequestHandler jest abstrakcją na szczycie HttpServletRequestServlet API. Niektóre z charakterystycznych cech gobelinu są wykonane wRequestHandlerSekcja. Funkcję tapestry można rozszerzyć, pisząc filtr w RequestHandler. RequestHandler zapewnia kilka wbudowanych filtrów, które obejmują -
CheckForUpdates Filter- Odpowiedzialny za przeładowywanie klas na żywo. Ten filtr sprawdza klasy Java pod kątem zmian iw razie potrzeby aktualizuje aplikację.
Localization Filter - Zidentyfikuj lokalizację użytkownika i zapewnij wsparcie lokalizacji dla aplikacji.
StaticFiles Filter- Zidentyfikuj żądanie statyczne i przerywa proces. Po przerwaniu procesu Java Servlet przejmuje kontrolę i przetwarza żądanie.
Error Filter - Przechwytuje nieprzechwycony wyjątek i wyświetla stronę z raportem wyjątków.
RequestHandler również modyfikuje i przechowuje żądanie i odpowiedź w RequestQlobals i wywołuje usługę MasterDispatcher.
Step 5 - The MasterDispatcherOdpowiada za renderowanie strony przez wywołanie kilku dyspozytorów to określone zamówienie. Czterech głównych dyspozytorów wywoływanych przez MasterDispatcher to:
RootPath Dispatcher - Rozpoznaje ścieżkę główną „/” żądania i renderuje to samo, co strona początkowa.
Asset Dispatcher - Rozpoznał żądanie zasobu (zasoby Java), sprawdzając wzorzec adresu URL / zasoby / i wysyła żądane zasoby jako strumienie bajtów.
PageRender Dispatcher- Masowe operacje na tapestry są wykonywane w PageRender Dispatcher i następnym Dispatcher Component Dispatcher. Ten dyspozytor rozpoznaje konkretną stronę tego żądania i jego kontekst aktywacji (dodatkowe informacje). Następnie renderuje tę konkretną stronę i wysyła ją do klienta. Na przykład, jeśli adres URL żądania to / produkt / 12123434, dyspozytor sprawdzi, czy jakakolwiek klasa o nazwie produkt / 12123434 jest dostępna. Jeśli zostanie znaleziony, wywołuje klasę product / 12123434, generuje odpowiedź i wysyła ją do klienta. Jeśli nie, sprawdza klasę produktu. Jeśli zostanie znaleziony, wywołuje klasę produktu z dodatkowymi informacjami 121234434, generuje odpowiedź i wysyła ją do klienta. Te dodatkowe informacje nazywają się kontekstem aktywacji. Jeśli żadna klasa nie zostanie znaleziona, po prostu przekazuje żądanie do dyspozytora składników.
Component Dispatcher- Component Dispatcher dopasowuje adres URL strony do wzorca - / <class_name> / <component_id>: <event_type> / <activation_context>. Na przykład / product / grid: sort / asc reprezentuje klasę produktu, składnik siatki, typ sortevent i kontekst aktywacji asc. Tutaj event_type jest opcjonalny i jeśli nie zostanie podany, zostanie uruchomiona domyślna akcja typu zdarzenia. Zwykle odpowiedzią dyspozytora komponentów jest wysłanie przekierowania do klienta. Przeważnie przekierowanie będzie pasowało do PageRender Dispatcher w następnym żądaniu, a do klienta zostanie wysłana odpowiednia odpowiedź.
W tym rozdziale omówimy, jak zainstalować Tapestry na naszym komputerze.
Warunek wstępny
Jedyną zależnością Tapestry jest Core Java. Tapestry jest rozwijane niezależnie, bez korzystania z biblioteki / frameworka stron trzecich. Nawet biblioteka IoC używana przez tapestry jest rozwijana od podstaw. Aplikację internetową napisaną w tapestry można budować i wdrażać z poziomu samej konsoli.
Możemy użyć Maven, Eclipse i Jettyaby ulepszyć doświadczenie programistyczne. Maven zapewnia szablony aplikacji szybkiego startu i opcje do hostowania aplikacji na Jetty, de facto serwerze programistycznym Java. Eclipse zapewnia rozbudowane funkcje zarządzania projektami i dobrze integruje się z maven.
Idealny program do tworzenia aplikacji tapestry wymaga:
- Java 1.6 lub nowsza
- Apache Maven
- Eclipse IDE
- Serwer Jetty
Sprawdź instalację Mavena
Mamy nadzieję, że zainstalowałeś Mavena na swoim komputerze. Aby zweryfikować instalację Mavena, wpisz polecenie podane poniżej -
mvn --version
Możesz zobaczyć odpowiedź, jak pokazano poniżej -
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"
Jeśli Maven nie jest zainstalowany, pobierz i zainstaluj najnowszą wersję mavena, odwiedzając witrynę internetową Maven .
Pobierz Tapestry
Najnowsza wersja Tapestry to 5.4 i można ją pobrać ze strony internetowej Tapestry . Wystarczy pobrać pakiet binarny . Jeśli korzystamy z szablonu Maven Quick Start, nie jest konieczne oddzielne pobieranie Tapestry. Maven automatycznie pobiera niezbędne słoiki Tapestry i konfiguruje aplikację. W następnym rozdziale omówimy sposób tworzenia podstawowej aplikacji Tapestry przy użyciu Mavena.
Po zainstalowaniu Tapestry stwórzmy nowy początkowy projekt za pomocą Mavena, jak pokazano poniżej -
$ mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org
Możesz zobaczyć odpowiedź, jak pokazano poniżej -
[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)
Po zbudowaniu przez Mavena wszystkich operacji wybierz archetyp do stworzenia Tapestry 5 QuickStart projekt w następujący sposób -
Choose archetype -
https://tapestry.apache.org → org.apache.tapestry: Szybki start (Projekt Tapestry 5 Quickstart)
https://tapestry.apache.org → org.apache.tapestry: tapestry-archetype (Tapestry 4.1.6 Archetype)
Wybierz liczbę lub zastosuj filtr (format: [groupId:] artifactId, rozróżniana wielkość liter zawiera):: 1
Teraz otrzymasz odpowiedź, taką jak pokazano poniżej -
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
Wyodrębnij numer wersji QuickStart w następujący sposób -
Choose a number: 5: 5
Tutaj projekt QuickStart przyjmuje wersję dla opcji 5, „5.4.1”. Teraz archetyp Tapestry pyta kolejno o następujące informacje:
5.1 groupId - Zdefiniuj wartość dla właściwości „groupId”:: com.example
5.2 artifactId - Określ wartość właściwości „artifactId”:: Myapp
5.3 version - Zdefiniuj wartość właściwości „wersja”: 1.0-SNAPSHOT::
5.4 package name - Zdefiniuj wartość dla właściwości „pakiet”: com.example:: com.example.Myapp
Teraz ekran prosi o potwierdzenie -
Potwierdź konfigurację właściwości -
groupId - com.example
artifactId - Myapp
version - 1.0-SNAPSHOT
package - com.example.Myapp
Sprawdź wszystkie właściwości i potwierdź zmiany za pomocą opcji pokazanej poniżej -
Y: : Y
Zobaczysz ekran podobny do pokazanego poniżej.
[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] ---------------------------------------------------------------------------------
Tutaj pomyślnie zbudowałeś projekt Szybki start Tapestry. Przenieś się do lokalizacji nowo utworzonegoMyapp katalog za pomocą następującego polecenia i rozpocznij kodowanie.
cd Myapp
Uruchom aplikację
Aby uruchomić projekt szkieletu, użyj następującego polecenia.
mvn jetty:run -Dtapestry.execution-mode=development
Dostajesz taki ekran,
[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
Na razie stworzyliśmy podstawowy projekt Szybki start w Tapestry. Aby wyświetlić uruchomioną aplikację w przeglądarce internetowej, po prostu wpisz następujący adres URL w pasku adresu i naciśnij enter -
https://localhost:8080/myapp
Tutaj, myapp to nazwa aplikacji, a domyślny port aplikacji w trybie programowania to 8080.
Korzystanie z Eclipse
W poprzednim rozdziale omówiliśmy sposób tworzenia aplikacji Szybki start Tapestry w CLI. W tym rozdziale opisano tworzenie szkieletowej aplikacji wEclipse IDE.
Użyjmy archetypu Mavena do stworzenia szkieletowej aplikacji. Aby skonfigurować nową aplikację, możesz wykonać poniższe czynności.
Krok 1: Otwórz Eclipse IDE
Otwórz Eclipse i wybierz opcję Plik → Nowy → Projekt… →, jak pokazano na poniższym zrzucie ekranu.
Teraz wybierz opcję Maven → Maven Project.
Note - Jeśli Maven nie jest skonfigurowany, skonfiguruj i utwórz projekt.
Po wybraniu projektu Maven kliknij Dalej i ponownie kliknij przycisk Dalej.
Następnie pojawi się ekran, na którym należy wybrać opcję konfiguracji. Po skonfigurowaniu pojawi się następujący ekran.
Krok 2: Konfiguracja katalogu
Po wykonaniu pierwszego kroku należy kliknąć Add Remote Catalog. Następnie dodaj następujące zmiany, jak pokazano na poniższym zrzucie ekranu.
Teraz dodano katalog Apache Tapestry. Następnie wybierz opcję filtru org.apache.tapestry quickstart 5.4.1, jak pokazano poniżej.
Następnie kliknij Dalej, a pojawi się następujący ekran.
Krok 3: Skonfiguruj GroupId, ArtifactId, wersję i pakiet
Dodaj następujące zmiany do konfiguracji katalogu Tapestry.
Następnie kliknij przycisk Zakończ, teraz stworzyliśmy pierwszą aplikację szkieletową. Przy pierwszym użyciu Mavena tworzenie projektu może trochę potrwać, ponieważ Maven pobiera wiele zależności JAR dla Maven, Jetty i Tapestry. Po zakończeniu pracy Maven zobaczysz nowy katalog, MyFirstApplication w widoku Eksploratora pakietów.
Krok 4: Uruchom aplikację przy użyciu serwera Jetty
Możesz użyć Maven do bezpośredniego uruchomienia Jetty. Kliknij prawym przyciskiem myszy projekt MyFirstApplication w widoku Eksploratora pakietów i wybierz Uruchom jako → Maven Build… pojawi się ekran pokazany poniżej.
W oknie dialogowym konfiguracji wpisz opcję celów jako „pomost: bieg”, a następnie kliknij przycisk Uruchom.
Po zainicjowaniu Jetty w konsoli zobaczysz następujący ekran.
Krok 5: Uruchom w przeglądarce internetowej
Wpisz następujący adres URL, aby uruchomić aplikację w przeglądarce internetowej -
https://loclhost:8080/MyFirstApplication
Krok 6: Zatrzymaj serwer Jetty
Aby zatrzymać serwer Jetty, kliknij ikonę czerwonego kwadratu w konsoli, jak pokazano poniżej.
Oto układ kodu źródłowego utworzonego przez Maven Quickstart CLI. Jest to również sugerowany układ standardowej aplikacji Tapestry.
├── 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
Domyślny układ jest ułożony jak WAR Internal File Format. Korzystanie z formatu WAR ułatwia uruchamianie aplikacji bez pakowania i wdrażania. Ten układ to tylko sugestia, ale aplikację można ustawić w dowolnym formacie, jeśli podczas wdrażania zostanie spakowana do odpowiedniego formatu WAR.
Kod źródłowy można podzielić na następujące cztery główne sekcje.
Java Code - Wszystkie kody źródłowe Java są umieszczone pod /src/main/javateczka. Klasy stron Tapestry są umieszczane w folderze „Strony”, a klasy komponentów Tapestry w folderze komponentów. Klasy usług Tapestry są umieszczane w folderze usług.
ClassPath Resources- W Tapestry większość klas ma powiązane zasoby (szablon XML, pliki JavaScript itp.). Te zasoby są umieszczane pod/src/main/resourcesteczka. Z klasami stron Tapestry są skojarzone zasoby w folderze „Strony”, a z klasami komponentów Tapestry w folderze Komponenty. Te zasoby są spakowane wWEB-INF/classes folder WAR.
Context Resources - Są to statyczne zasoby aplikacji internetowej, takie jak obrazy, arkusz stylów i biblioteka JavaScript / Modules. They are usually placed under the /src/main/webapp folder i są nazywane Context Resources. Ponadto plik opisu aplikacji internetowej (Java Servlet), web.xml jest umieszczony podWEB-INF folder zasobów kontekstowych.
Testing Code - Są to opcjonalne pliki używane do testowania aplikacji i umieszczane pod src/test/java i src/test/Foldery zasobów. Nie są pakowani do WAR.
Następuje Apache Tapestry Convention over Configurationw każdym aspekcie programowania. Każda funkcja frameworka ma rozsądną domyślną konwencję.
Na przykład, jak dowiedzieliśmy się w rozdziale Układ projektu, wszystkie strony muszą być umieszczone w pliku /src/main/java/«package_path»/pages/ należy traktować jako strony Tapestry.
W innym sensie nie ma potrzeby konfigurowania określonej klasy Java jako stron Tapestry. Wystarczy umieścić zajęcia w ustalonym wcześniej miejscu. W niektórych przypadkach dziwne jest przestrzeganie domyślnej konwencji Tapestry.
Na przykład komponent Tapestry może mieć metodę setupRenderktóry zostanie uruchomiony na początku fazy renderowania. Na przykład deweloper może chcieć użyć własnej, opiniowanej nazwyinitializeValue. W takiej sytuacji zapewnia TapestryAnnotation aby zastąpić konwencje, jak pokazano w poniższym bloku kodu.
void setupRender() {
// initialize component
}
@SetupRender
void initializeValue() {
// initialize component
}
W Tapestry obowiązują oba sposoby programowania. Krótko mówiąc, domyślna konfiguracja Tapestry jest dość minimalna. TylkoApache Tapestry Filter (Java Servlet Filter) musi być skonfigurowany w „Web.xml”, aby aplikacja działała poprawnie.
Tapestry zapewnia inny sposób konfigurowania aplikacji i jest nazywany AppModule.java.
Adnotacja to bardzo ważna funkcja wykorzystywana przez Tapestry do uproszczenia tworzenia aplikacji internetowych. Tapestry zapewnia wiele niestandardowych adnotacji. Posiada adnotacje dla klas, metod i pól członkowskich. Jak omówiono w poprzedniej sekcji, Adnotacje mogą być również używane do zastępowania domyślnej konwencji funkcji. Adnotacje z tkaniny są pogrupowane w cztery główne kategorie i są one następujące.
Opis komponentu
Używany w klasach Pages, Components i Mixins. Niektóre z przydatnych adnotacji to:
@Property- Ma zastosowanie do pól. Służy do przekształcania pola w Właściwość Tapestry.
@Parameter- Ma zastosowanie do pól. Służy do określania pola jako parametru komponentu.
@Environmental- Ma zastosowanie do pól. Służy do udostępniania prywatnego pola między różnymi komponentami.
@import- Dotyczy klas i dziedzin. Używane do uwzględniania zasobów, CSS i JavaScript.
@Path - Używany w połączeniu z adnotacją @Inject w celu wstrzyknięcia zasobu na podstawie ścieżki.
@Log- Dotyczy klas i dziedzin. Używany do celów debugowania. Można użyć informacji o zdarzeniach komponentu emitowania, takich jak początek, koniec zdarzenia itp.
Adnotacja IoC
Służy do wstrzykiwania obiektów do kontenera IoC. Niektóre z przydatnych adnotacji to:
@Inject- Ma zastosowanie do pól. Służy do oznaczania parametrów, które powinny zostać wstrzyknięte do kontenera IoC. Zaznacza pola, które należy wstrzyknąć do komponentów.
@Value- Ma zastosowanie do pól. Używane wraz z adnotacją @inject do wstrzyknięcia wartości literału zamiast usługi (co jest domyślnym zachowaniem adnotacji @Inject).
Adnotacja dla klas przechowywania danych
Służy do określania informacji specyficznych dla komponentu w klasie (zwykle modele lub klasy przechowywania danych) dla komponentów wysokiego poziomu, takich jak
Grid (służy do tworzenia zaawansowanych danych tabelarycznych, takich jak raport, galeria itp.)
BeanEditForm (Służy do tworzenia zaawansowanych formularzy)
Hibernate (Używany w zaawansowanym dostępie do bazy danych) itp.
Te adnotacje są agregowane i pakowane w osobny słoik bez żadnej zależności od tkaniny. Niektóre adnotacje to -
@DataType- Służy do określenia typu danych pola. Komponent Tapestry może wykorzystywać te informacje do tworzenia projektu lub znaczników w warstwie prezentacji.
@Validate - Służy do określenia reguły walidacji dla pola.
Te rozbarwienia umożliwiają aplikacji Tapestry używanie pliku Multi-Tier Design.
Aplikacja Tapestry to po prostu zbiór stron Tapestry. Pracują razem, tworząc dobrze zdefiniowaną aplikację internetową. Każda strona będzie miała odpowiedni szablon XML i zero, jeden lub więcej składników. Strona i składnik są takie same, z wyjątkiem tego, że strona jest składnikiem głównym i zwykle jest tworzona przez programistę aplikacji.
Components are children of the root Pagecomponent. Tapestry ma wiele wbudowanych komponentów i ma opcję tworzenia niestandardowych komponentów.
Strony
Jak wspomniano wcześniej, Strony są elementami składowymi aplikacji Tapestry. Strony są zwykłymi POJO, umieszczonymi pod -/src/main/java/«package_path»/pages/teczka. Każda strona będzie miała odpowiedni plikXML Template a jego domyślna lokalizacja to - /src/main/resources/«package_name»/pages/.
Możesz zobaczyć tutaj, że struktura ścieżki jest podobna dla strony i szablonu, z wyjątkiem tego, że szablon znajduje się w Resource Folder.
Na przykład strona rejestracji użytkownika w aplikacji Tapestry z nazwą pakietu - com.example.MyFirstApplication będzie mieć następujące pliki stron i szablonów -
Java Class -
/src/main/java/com/example/MyFirstApplication/pages/index.java
XML Template -
/src/main/resources/com/example/MyFirstApplication/pages/index.tml
Stwórzmy prosty Hello Worldstrona. Najpierw musimy utworzyć plikJava Class at - /src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java ”.
package com.example.MyFirstApplication.pages;
public class HelloWorld {
}
Następnie utwórz szablon XML pod adresem -
„/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>
Teraz ta strona jest dostępna pod adresem https://localhost:8080/myapp/helloworld. To jest prosta strona z gobelinem. Tapestry oferuje znacznie więcej funkcji do tworzenia dynamicznych stron internetowych, które omówimy w następnych rozdziałach.
Rozważmy w tej sekcji szablon Tapestry XML. Szablon XML to dobrze sformułowany dokument XML. Warstwa prezentacji (interfejsu użytkownika) strony to szablon XML. Szablon XML ma normalne znaczniki HTML oprócz elementów podanych poniżej -
- Przestrzeń nazw Tapestry
- Expansions
- Elements
- Components
Omówmy je teraz szczegółowo.
Przestrzeń nazw Tapestry
Przestrzenie nazw Tapestry to nic innego jak przestrzenie nazw XML. Przestrzenie nazw należy zdefiniować w elemencie głównym szablonu. Służy do dołączania komponentów tapestry i informacji związanych z komponentami w szablonie. Najczęściej używane przestrzenie nazw są następujące -
xmlns: t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” - Służy do identyfikacji elementów, składników i atrybutów Tapestry.
xmlns: p = „tapestry: parameter” - Służy do przekazywania dowolnych fragmentów kodu do komponentów.
Przykład przestrzeni nazw Tapestry jest następujący -
<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>
Rozszerzenia
Rozszerzanie to prosta i wydajna metoda dynamicznej zmiany szablonu XML podczas fazy renderowania strony. Rozwinięcie używa składni $ {<name>}. Istnieje wiele opcji wyrażenia rozszerzenia w szablonie XML. Zobaczmy niektóre z najczęściej używanych opcji -
Rozbudowa nieruchomości
Mapuje właściwość zdefiniowaną w odpowiedniej klasie Page. Jest zgodny ze specyfikacją Java Bean dla definicji właściwości w klasie Java. To idzie o krok dalej, ignorując przypadki w nazwie właściwości. Zmieńmy przykład „Hello World” za pomocą rozszerzenia właściwości. Poniższy blok kodu to zmodyfikowana klasa Page.
package com.example.MyFirstApplication.pages;
public class HelloWorld {
// Java Bean Property
public String getName {
return "World!";
}
}
Następnie zmień odpowiedni szablon XML, jak pokazano poniżej.
<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>
Tutaj zdefiniowaliśmy name tak jak Java Bean Property w klasie Page i dynamicznie przetwarzane w szablonie XML za pomocą rozszerzenia ${name}.
Rozszerzenie wiadomości
Każda klasa strony może mieć powiązany plik właściwości lub nie - «page_name».propertiesw folderze zasobów. Pliki właściwości to zwykłe pliki tekstowe zawierające jedną parę klucz / wartość (komunikat) w każdym wierszu. Utwórzmy plik właściwości dla strony HelloWorld w -
„/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties” i dodaj wiadomość „Powitanie”.
Greeting = Hello
Plik Greeting wiadomość może być używana w szablonie XML jako ${message:greeting}
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>Hello World Page</title>
</head>
<body>
<!-- expansion -->
<h1>${message:greeting} ${name}</h1>
</body>
</html>
Elementy
Tapestry zawiera niewielki zestaw elementów do wykorzystania w szablonach XML. Elementy to predefiniowane znaczniki zdefiniowane w przestrzeni nazw Tapestry -
https://tapestry.apache.org/schema/tapestry_5_4.xsd
Każdy element jest tworzony w określonym celu. Dostępne elementy gobelinu są następujące -
<t: body>
Kiedy dwa komponenty są zagnieżdżone, szablon komponentu nadrzędnego może wymagać zawijania szablonu komponentu potomnego. W tej sytuacji przydatny jest element <t: body>. Jednym z zastosowań <t: body> jest układ szablonu.
Ogólnie interfejs użytkownika aplikacji internetowej będzie miał wspólny nagłówek, stopkę, menu itd. Te wspólne elementy są zdefiniowane w szablonie XML i nazywa się to Układ szablonu lub Komponent układu. W Tapestry musi zostać utworzony przez programistę aplikacji. Komponent układu to tylko kolejny komponent i jest umieszczany w folderze komponentów, który ma następującą ścieżkę -src/main/«java|resources»/«package_name»/components.
Utwórzmy prosty komponent układu o nazwie MyCustomLayout. Kod MyCustomLayout jest następujący -
<!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;
}
W klasie składnika MyCustomLayout zadeklarowaliśmy pole tytułu i za pomocą adnotacji uczyniliśmy je obowiązkowym. Teraz zmień szablon HelloWorld.html, aby używał naszego niestandardowego układu, jak pokazano w bloku kodu poniżej.
<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>
Widzimy tutaj, że szablon XML nie ma tagów head i body. Tapestry zbierze te szczegóły z komponentu układu, a <t: body> komponentu układu zostanie zastąpione szablonem HelloWorld. Gdy wszystko zostanie zrobione, Tapestry wyemituje podobne znaczniki, jak określono poniżej -
<!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>
Układy można zagnieżdżać. Na przykład możemy rozszerzyć nasz niestandardowy układ, włączając funkcje administracyjne i używać go w sekcji administracyjnej, jak określono poniżej.
<html t:type = "MyCommonLayout"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<div><!-- Admin related items --><div>
<t:body/>
</html>
<t: pojemnik>
<T: container> jest elementem najwyższego poziomu i zawiera przestrzeń nazw tapestry. Służy do określenia dynamicznej sekcji komponentu.
Na przykład komponent siatki może wymagać szablonu, aby określić, jak renderować wiersze - tr (i kolumnę td) w tabeli HTML.
<t:container xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<td>${name}</td>
<td>${age}</td>
</t:container>
<t: block>
<T: block> jest symbolem zastępczym dynamicznej sekcji w szablonie. Ogólnie rzecz biorąc, element blokowy nie jest renderowany. Tylko komponenty zdefiniowane w szablonie używają elementu blokowego. Komponenty będą wprowadzać dane dynamicznie do elementu bloku i renderować go. Jednym z popularnych przypadków użycia jestAJAX.
Element bloku zapewnia dokładną pozycję i znaczniki dla renderowanych danych dynamicznych. Każdy element bloku powinien mieć odpowiednią właściwość Java. Dopiero wtedy można go renderować dynamicznie. Identyfikator elementu bloku powinien być zgodny z regułami identyfikatorów zmiennych Java. Poniżej przedstawiono przykładowy fragment.
@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>
Element <t: content> służy do określenia faktycznej zawartości szablonu. Ogólnie rzecz biorąc, wszystkie znaczniki są uważane za część szablonu. Jeśli określono <t: content>, pod uwagę brany będzie tylko znacznik wewnątrz niego. Ta funkcja jest używana przez projektantów do projektowania strony bez składnika układu.
<t: remove>
Element <t: remove> jest przeciwieństwem elementu content. Znacznik wewnątrz elementu remove nie jest uważany za część szablonu. Może być używany tylko do komentarzy na serwerze i do celów projektowych.
Majątek
Zasoby to statyczne pliki zasobów, takie jak arkusze stylów, obrazy i pliki JavaScript. Zwykle zasoby są umieszczane w katalogu głównym aplikacji internetowej/src/main/webapp.
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestry traktuje również pliki przechowywane w formacie Java Classpathjako aktywa. Tapestry zapewnia zaawansowane opcje dołączania zasobów do szablonu poprzez opcję rozszerzenia.
Context - Możliwość uzyskania zasobów dostępnych w kontekście internetowym.
<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>
asset- Komponenty zwykle przechowują własne zasoby w pliku jar wraz z klasami Java. Począwszy od Tapestry 5.4, standardowa ścieżka do przechowywania zasobów w ścieżce klas toMETA-INF/assets. W przypadku bibliotek standardowa ścieżka do przechowywania zasobów toMETA-INF/assets/«library_name»/. asset: można też zadzwonić context: ekspansja w celu uzyskania zasobów z kontekstu internetowego.
<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>
Zasoby można wstrzykiwać do strony Tapestry lub komponentu za pomocą adnotacji Inject i Path. Parametr adnotacji Path to względna ścieżka zasobów.
@Inject
@Path("images/edit.png")
private Asset icon;
Plik Path parameter może również zawierać symbole Tapestry zdefiniowane w AppModule.java Sekcja.
Na przykład możemy zdefiniować symbol skin.root z kontekstem wartości: skins / basic i użyć go, jak pokazano poniżej -
@Inject
@Path("${skin.root}/style.css")
private Asset style;
Lokalizacja
Dołączanie zasobów za pomocą tkaniny zapewnia dodatkową funkcjonalność. Jedną z takich funkcji jest „Lokalizacja”. Tapestry sprawdzi aktualne ustawienia regionalne i uwzględni odpowiednie zasoby.
Na przykład, jeśli bieżące ustawienia regionalne są ustawione jako de, następnie edit_de.png zostanie dołączony zamiast edit.png.
CSS
Tapestry ma wbudowaną obsługę arkuszy stylów. Gobelin wstrzyknietapestry.cssjako część podstawowego stosu Javascript. Od Tapestry 5.4, Tapestry zawierabootstrap css frameworktakże. Możemy dołączyć własny arkusz stylów za pomocą zwykłego tagu linku. W takim przypadku arkusze stylów powinny znajdować się w głównym katalogu WWW -/src/main/webapp/.
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestry zapewnia zaawansowane opcje dołączania arkuszy stylów do szablonu poprzez opcję rozszerzenia, jak omówiono wcześniej.
<head>
<link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>
Tapestry udostępnia również adnotację Import, która umożliwia dołączenie arkusza stylów bezpośrednio do klas Java.
@Import(stylesheet="context:css/site.css")
public class MyCommonLayout {
}
Tapestry zapewnia wiele opcji zarządzania arkuszami stylów poprzez AppModule.java. Niektóre z ważnych opcji to -
Domyślny arkusz stylów gobelinu może zostać usunięty.
@Contribute(MarkupRenderer.class)
public static void
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) {
configuration.override("InjectDefaultStyleheet", null);
}
Bootstrap można również wyłączyć, zastępując jego ścieżkę.
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
Włącz dynamiczne minimalizowanie zasobów (CSS i JavaScript). Musimy uwzględnićtapestry-webresources zależność (w 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 po stronie klienta
Obecna generacja aplikacji internetowych w dużym stopniu zależy od JavaScript, aby zapewnić bogate wrażenia po stronie klienta. Tapestry to potwierdza i zapewnia obsługę JavaScript pierwszej klasy. Obsługa JavaScript jest głęboko zakorzeniona w gobelinie i jest dostępna na każdym etapie programowania.
Wcześniej Tapestry obsługiwał tylko Prototype i Scriptaculous. Jednak począwszy od wersji 5.4, tapestry całkowicie przepisał warstwę JavaScript, aby uczynić ją możliwie najbardziej ogólną i zapewnić obsługę pierwszej klasy dla JQuery, de facto biblioteki JavaScript. Tapestry zachęca również do programowania JavaScript opartego na modułach i obsługuje RequireJS, popularną implementację AMD po stronie klienta (Asynchronous Module Definition - specyfikacja JavaScript do obsługi modułów i ich zależności w sposób asynchroniczny).
Lokalizacja
Pliki JavaScript są zasobami aplikacji Tapestry. Zgodnie z regułami dotyczącymi zasobów pliki JavaScript są umieszczane w kontekście sieciowym,/sr/main/webapp/ lub umieścić w słoiku pod META-INF/assets/ location.
Łączenie plików JavaScript
Najprostszym sposobem łączenia plików JavaScript w szablonie XML jest bezpośrednie użycie tagu script, którym jest - <script language = "javascript" src = "relative/path/to/js"></script>. Ale gobelin nie zaleca takich podejść. Tapestry udostępnia kilka opcji łączenia plików JavaScript bezpośrednio w samej stronie / komponencie. Niektóre z nich podano poniżej.
@import annotation- Adnotacja @import zapewnia opcję łączenia wielu bibliotek JavaScript za pomocą wyrażenia kontekstowego. Można ją zastosować zarówno do klasy Page, jak i do jej metody. Jeśli zostanie zastosowana do klasy Page, ma zastosowanie do wszystkich jej metod. Jeśli zostanie zastosowana do metody strony, ma zastosowanie tylko do tej metody, a następnie Tapestry łączy bibliotekę JavaScript tylko wtedy, gdy metoda jest wywoływana.
@Import(library = {"context:js/jquery.js","context:js/myeffects.js"})
public class MyComponent {
// ...
}
JavaScriptSupport interface - JavaScriptSupport to interfejs zdefiniowany przez tapestry i ma metodę, importJavaScriptLibrarydo importowania plików JavaScript. Obiekt JavScriptSupport można łatwo utworzyć, po prostu deklarując i dodając adnotacje za pomocą adnotacji @Environmental.
@Inject @Path("context:/js/myeffects.js")
private Asset myEffects;
@Environmental
private JavaScriptSupport javaScriptSupport;
void setupRender() {
javaScriptSupport.importJavaScriptLibrary(myEffects);
}
JavaScripSupport można wstrzyknąć tylko do składnika przy użyciu rozszerzenia @Environmentaladnotacja. W przypadku usług musimy użyć rozszerzenia@Inject adnotację lub dodaj jako argument w metodzie konstruktora usługi.
@Inject
private JavaScriptSupport javaScriptSupport;
public MyServiceImpl(JavaScriptSupport support) {
// ...
}
addScript method - Jest to podobne do interfejsu JavaScriptSupport, z tym wyjątkiem, że używa rozszerzenia addScript , a kod jest dodawany bezpośrednio do danych wyjściowych na dole strony.
void afterRender() {
javaScriptSupport.addScript(
"$('%s').observe('click', hideMe());", container.getClientId());
}
Stos JavaScript
Tapestry pozwala na połączenie grup plików JavaScript i powiązanych arkuszy stylów i używanie ich jako jednej całości. Obecnie Tapestry zawiera stosy oparte na prototypie i JQuery.
Deweloper może opracować własne stosy, implementując JavaScriptStack interfejs i zarejestruj go w AppModule.java. Po zarejestrowaniu stos można zaimportować przy użyciu rozszerzenia@import adnotacja.
@Contribute(JavaScriptStackSource.class)
public static void addMyStack(
MappedConfiguration<String, JavaScriptStack> configuration) {
configuration.addInstance("MyStack", myStack.class);
}
@Import(stack = "MyStack")
public class myPage {
}
Jak wspomniano wcześniej, składniki i strony są takie same, z wyjątkiem tego, że Page jest składnikiem głównym i zawiera jeden lub więcej składników podrzędnych. Komponenty zawsze znajdują się wewnątrz strony i wykonują prawie całą dynamiczną funkcjonalność strony.
Komponenty Tapestry renderują proste łącza HTML do złożonych funkcji siatki z interactive AJAX. Komponent może również zawierać inny komponent. Elementy gobelinu składają się z następujących elementów -
Component Class - główna klasa Java komponentu.
XML Template- Szablon XML jest podobny do szablonu strony. Klasa komponentu renderuje szablon jako ostateczne dane wyjściowe. Niektóre komponenty mogą nie mieć szablonów. W takim przypadku dane wyjściowe zostaną wygenerowane przez samą klasę komponentów przy użyciuMarkupWriter klasa.
Body- Komponent określony w szablonie strony może mieć niestandardowe znaczniki i nosi nazwę „Treść komponentu”. Jeśli szablon komponentu ma<body />element, wówczas element <body /> zostanie zastąpiony treścią komponentu. Jest to podobne do układu omówionego wcześniej w sekcji dotyczącej szablonów XML.
Rendering - Rendering to proces, który przekształca szablon XML i treść komponentu w rzeczywisty wynik komponentu.
Parameters - Służy do tworzenia komunikacji między komponentami i stronami, a tym samym do przekazywania danych między nimi.
Events- Deleguje funkcjonalność z komponentów do swojego kontenera / elementu nadrzędnego (strony lub inny komponent). Jest szeroko stosowany w celu nawigacji po stronach.
Wykonanie
Renderowanie komponentu odbywa się w szeregu wstępnie zdefiniowanych faz. Każda faza w systemie komponentów powinna mieć odpowiednią metodę zdefiniowaną przez konwencję lub adnotację w klasie komponentów.
// Using annotaion
@SetupRender
void initializeValues() {
// initialize values
}
// using convention
boolean afterRender() {
// do logic
return true;
}
Fazy, nazwa metody i adnotacje są wymienione poniżej.
Adnotacja | Domyślne nazwy metod |
---|---|
@SetupRender | setupRender () |
@BeginRender | beginRender () |
@BeforeRenderTemplate | beforeRenderTemplate () |
@BeforeRenderBody | beforeRenderBody () |
@AfterRenderBody | afterRenderBody () |
@AfterRenderTemplate | afterRenderTemplate () |
@AfterRender | afterRender () |
@CleanupRender | cleanupRender () |
Każda faza ma określony cel i są one następujące -
SetupRender
SetupRender uruchamia proces renderowania. Zwykle ustawia parametry komponentu.
BeginRender
BeginRender rozpoczyna renderowanie składnika. Zwykle renderuje początkowy / początkowy znacznik komponentu.
BeforeRenderTemplate
BeforeRenderTemplate służy do ozdabiania szablonu XML, dodając specjalne znaczniki wokół szablonu. Zapewnia również opcję pominięcia renderowania szablonu.
BeforeRenderBody
BeforeRenderTemplate zapewnia opcję pomijania renderowania elementu treści składnika.
AfterRenderBody
AfterRenderBody zostanie wywołane po wyrenderowaniu treści składnika.
AfterRenderTemplate
AfterRenderTemplate zostanie wywołany po wyrenderowaniu szablonu składnika.
AfterRender
AfterRender jest odpowiednikiem BeginRender i zwykle renderuje znacznik zamknięcia.
CleanupRender
CleanupRender jest odpowiednikiem SetupRender. Zwalnia / usuwa wszystkie obiekty utworzone podczas procesu renderowania.
Przepływ faz renderowania jest nie tylko naprzód. Przechodzi tam iz powrotem między fazami w zależności od wartości zwracanej fazy.
Na przykład, jeśli metoda SetupRender zwraca wartość false, renderowanie przechodzi do fazy CleanupRender i odwrotnie. Aby dokładnie zrozumieć przepływ między różnymi fazami, sprawdź przepływ na poniższym schemacie.
Prosty komponent
Stwórzmy prosty komponent Hello, który będzie miał komunikat wyjściowy „Hello, Tapestry”. Poniżej znajduje się kod składnika Hello i jego szablon.
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>
Komponent Hello można wywołać w szablonie strony jako -
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:hello />
</html>
Podobnie składnik może renderować te same dane wyjściowe przy użyciu MarkupWriter zamiast szablonu, jak pokazano poniżej.
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>");
}
}
Zmieńmy szablon komponentu i dołączmy element <body />, jak pokazano w bloku kodu poniżej.
<html>
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div>
<t:body />
</div>
</html>
Teraz szablon strony może zawierać treść w znaczniku komponentu, jak pokazano poniżej.
<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>
Dane wyjściowe będą następujące -
<html>
<div>
<p>Hello, Tapestry (from page).</p>
</div>
</html>
Parametry
Głównym celem tych parametrów jest utworzenie połączenia między polem komponentu a właściwością / zasobem strony. Za pomocą parametrów, komponent i odpowiadająca mu strona komunikują się i przesyłają dane między sobą. To się nazywaTwo Way Data Binding.
Na przykład składnik pola tekstowego używany do reprezentowania wieku na stronie zarządzania użytkownikami pobiera swoją wartość początkową (dostępną w bazie danych) za pośrednictwem parametru. Ponownie, po zaktualizowaniu i odesłaniu wieku użytkownika komponent odeśle zaktualizowany wiek za pomocą tego samego parametru.
Aby utworzyć nowy parametr w klasie komponentu, zadeklaruj pole i określ @Parameteradnotacja. Ten parametr @Parameter ma dwa opcjonalne argumenty, którymi są -
required- ustawia parametr jako obowiązkowy. Gobelin stanowi wyjątek, jeśli nie jest dostarczony.
value - określa domyślną wartość parametru.
Parametr powinien być określony w szablonie strony jako atrybuty tagu komponentu. Wartość atrybutów należy określić za pomocą wyrażenia / rozszerzenia powiązania, które omówiliśmy we wcześniejszych rozdziałach. Niektóre z rozszerzeń, których nauczyliśmy się wcześniej, to:
Property expansion (prop:«val») - Pobierz dane z właściwości klasy strony.
Message expansion (message:«val») - Pobierz dane z klucza zdefiniowanego w pliku index.properties.
Context expansion (context:«val») - Pobierz dane z folderu kontekstu internetowego / src / main / webapp.
Asset expansion (asset:«val») - Pobierz dane z zasobów osadzonych w pliku jar, / META-INF / asset.
Symbol expansion (symbol:«val») - Pobierz dane z symboli zdefiniowanych w AppModule.javafile.
Tapestry ma wiele innych przydatnych rozszerzeń, z których niektóre podano poniżej -
Literal expansion (literal:«val») - Dosłowny ciąg.
Var expansion (var:«val») - Zezwól na odczyt lub aktualizację zmiennej renderowania komponentu.
Validate expansion (validate:«val»)- Specjalny ciąg używany do określenia reguły walidacji obiektu. Na przykład validate: required, minLength = 5.
Translate (translate:«val») - Służy do określania klasy Translator (konwertowania reprezentacji po stronie klienta na reprezentację po stronie serwera) podczas sprawdzania poprawności danych wejściowych.
Block (block:«val») - identyfikator elementu bloku w szablonie.
Component (component:«val») - identyfikator innego komponentu w szablonie.
Wszystkie powyższe rozszerzenia są tylko do odczytu, z wyjątkiem rozszerzenia Property i rozszerzenia Var. Są używane przez komponent do wymiany danych ze stroną. Używając rozwinięcia jako wartości atrybutów,${...}nie powinny być używane. Zamiast tego po prostu użyj rozszerzenia bez symboli dolara i nawiasów klamrowych.
Komponent wykorzystujący parametr
Utwórzmy nowy składnik HelloWithParameter, modyfikując składnik Hello, aby dynamicznie renderował komunikat, dodając name parametr w klasie komponentów i odpowiednio zmieniając szablon komponentu i szablon strony.
Utwórz nową klasę komponentów HelloWithParameter.java.
Dodaj pole prywatne i nadaj mu nazwę @Parameteradnotacja. Użyj wymaganego argumentu, aby uczynić go obowiązkowym.
@Parameter(required = true)
private String name;
Dodaj pole prywatne, wynik za pomocą @Properyadnotacja. Właściwość result zostanie użyta w szablonie komponentu. Szablon komponentu nie ma dostępu do pól z adnotacjami@Parameter i mieć dostęp tylko do pól oznaczonych @Property. Zmienne dostępne w szablonach komponentów noszą nazwę Zmienne renderowania.
@Property
private String result;
Dodaj metodę RenderBody i skopiuj wartość z parametru name do właściwości result.
@BeginRender
void initializeValues() {
result = name;
}
Dodaj nowy szablon komponentu HelloWithParamter.tml i użyj właściwości result do renderowania wiadomości.
<div> Hello, ${result} </div>
Dodaj nową właściwość Nazwa użytkownika na stronie testowej (testhello.java).
public String getUsername() {
return "User1";
}
Użyj nowo utworzonego komponentu w szablonie strony i ustaw właściwość Nazwa użytkownika w parametrze nazwa HelloWithParameter składnik.
<t:helloWithParameter name = "username" />
Pełna lista jest następująca -
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>
Wynik będzie następujący -
<div> Hello, User1 </div>
Parametr zaawansowany
W poprzednich rozdziałach przeanalizowaliśmy sposób tworzenia i używania prostego parametru w komponencie użytkownika. Zaawansowany parametr może również zawierać pełne znaczniki. W takim przypadku znacznik należy określić wewnątrz tagu komponentu, takiego jak podsekcja w szablonie strony. Wbudowany składnik if ma znaczniki zarówno dla warunku sukcesu, jak i niepowodzenia. Znacznik sukcesu jest określony jako treść znacznika składnika, a znacznik niepowodzenia jest określany za pomocąelseparameter.
Zobaczmy, jak używać ifskładnik. Komponent if ma dwa parametry -
test - Prosty parametr oparty na właściwościach.
Else - Zaawansowany parametr używany do określenia alternatywnych znaczników, jeśli warunek nie powiedzie się
Tapestry sprawdzi wartość właściwości test przy użyciu następującej logiki i zwróci wartość true lub false. To się nazywaType Coercion, sposób na konwersję obiektu jednego typu na inny o tej samej zawartości.
Jeśli typ danych to String, „Prawda”, jeśli nie jest pusta, a nie literał „Fałsz” (bez rozróżniania wielkości liter).
Jeśli typ danych to Number, Prawda, jeśli niezerowa.
Jeśli typ danych to Collection, Prawda, jeśli niepusty.
Jeśli typ danych to Object, Prawda (o ile nie jest zerowa).
Jeśli warunek zostanie spełniony, składnik renderuje swoją treść; w przeciwnym razie renderuje treść parametru else.
Pełna lista jest następująca -
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>
Zdarzenia komponentów / nawigacja po stronach
Aplikacja Tapestry to collection of Pageswspółdziałanie ze sobą. Do tej pory nauczyliśmy się tworzyć pojedyncze strony bez żadnej komunikacji między nimi. Głównym celem zdarzenia Component jest zapewnienie interakcji między stronami (także w obrębie stron) za pomocą zdarzeń po stronie serwera. Większość zdarzeń składowych pochodzi ze zdarzeń po stronie klienta.
Na przykład, gdy użytkownik kliknie łącze na stronie, Tapestry wywoła samą stronę z informacjami docelowymi zamiast wywoływać stronę docelową i wywoła zdarzenie po stronie serwera. Strona Tapestry przechwyci zdarzenie, przetworzy informacje docelowe i wykona przekierowanie po stronie serwera na stronę docelową.
Gobelin następuje po Post/Redirect/Get (RPG) design patterndo nawigacji po stronach. W RPG, gdy użytkownik wysyła żądanie wpisu, przesyłając formularz, serwer przetwarza przesłane dane, ale nie zwraca bezpośrednio odpowiedzi. Zamiast tego wykona przekierowanie po stronie klienta na inną stronę, która wyświetli wynik. Wzorzec RPG służy do zapobiegania zduplikowanym przesyłaniu formularzy za pomocą przycisku Wstecz przeglądarki, przycisku odświeżania przeglądarki itp. Tapestry zapewnia wzorzec RPG, zapewniając następujące dwa typy żądań.
Component Event Request- Ten typ żądania jest skierowany do określonego komponentu na stronie i wywołuje zdarzenia w tym komponencie. To żądanie służy tylko do przekierowania i nie wyświetla odpowiedzi.
Render Request - Te typy żądań dotyczą strony i przesyłają odpowiedź strumieniowo z powrotem do klienta.
Aby zrozumieć zdarzenia komponentu i nawigację po stronie, musimy znać wzorzec adresu URL żądania gobelinu. Wzorzec adresu URL dla obu typów żądań jest następujący -
Component Event Requests -
/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
Render Request -
/<<page_name_with_path>>/<<context_information>>
Oto niektóre przykłady wzorców adresów URL:
O stronę indeksową można poprosić przez https://«domain»/«app»/index.
Jeśli strona indeksu jest dostępna w podfolderze admin, można o nią poprosić https://«domain»/«app»/admin/index.
Jeśli użytkownik kliknie plik ActionLink component z id test na stronie indeksu, to adres URL będzie https://«domain»/«app»/index.test.
Wydarzenia
Domyślnie Tapestry podnosi się OnPassivate i OnActivatewydarzenia dla wszystkich wniosków. W przypadku typu żądania zdarzenia komponentu tapestry wywołuje dodatkowe jedno lub więcej zdarzeń w zależności od komponentu. Składnik ActionLink wywołuje zdarzenie Action, a składnik Form wywołuje wiele zdarzeń, takich jakValidate, Successitp.,
Zdarzenia mogą być obsługiwane w klasie strony przy użyciu odpowiedniej procedury obsługi metody. Procedura obsługi metody jest tworzona za pomocą konwencji nazewnictwa metod lub za pomocą@OnEventadnotacja. Format konwencji nazewnictwa metod toOn«EventName»From«ComponentId».
Zdarzenie akcji składnika ActionLink z id test można obsłużyć jedną z następujących metod -
void OnActionFromTest() {
}
@OnEvent(component = "test", name = "action")
void CustomFunctionName() {
}
Jeśli nazwa metody nie zawiera żadnego określonego składnika, metoda zostanie wywołana dla wszystkich składników z pasującymi zdarzeniami.
void OnAction() {
}
Zdarzenie OnPassivate i OnActivate
OnPassivate służy do dostarczania informacji kontekstowych dla procedury obsługi zdarzeń OnActivate. Ogólnie rzecz biorąc, Tapestry zapewnia informacje o kontekście i może być używany jako argument w module obsługi OnActivateevent.
Na przykład, jeśli informacje o kontekście są typu int 3, to zdarzenie OnActivate można wywołać jako -
void OnActivate(int id) {
}
W niektórych przypadkach informacje kontekstowe mogą być niedostępne. W takiej sytuacji możemy dostarczyć informacje o kontekście do obsługi zdarzeń OnActivate za pośrednictwem modułu obsługi zdarzeń OnPassivate. Zwracany typ procedury obsługi zdarzeń OnPassivate powinien być używany jako argument procedury obsługi zdarzeń OnActivate.
int OnPassivate() {
int id = 3;
return id;
}
void OnActivate(int id) {
}
Zwracane wartości obsługi zdarzeń
Tapestry powoduje przekierowanie stron na podstawie wartości zwracanych przez program obsługi zdarzeń. Procedura obsługi zdarzeń powinna zwracać jedną z następujących wartości.
Null Response- Zwraca wartość null. Tapestry utworzy adres URL bieżącej strony i wyśle do klienta jako przekierowanie.
public Object onAction() {
return null;
}
String Response- Zwraca wartość ciągu. Tapestry utworzy adres URL strony pasującej do wartości i wyśle do klienta jako przekierowanie.
public String onAction() {
return "Index";
}
Class Response- Zwraca klasę strony. Tapestry utworzy adres URL zwróconej klasy strony i wyśle do klienta jako przekierowanie.
public Object onAction() {
return Index.class
}
Page Response- Zwraca pole z adnotacją @InjectPage. Tapestry utworzy adres URL wstrzykniętej strony i wyśle do klienta jako przekierowanie.
@InjectPage
private Index index;
public Object onAction(){
return index;
}
HttpError- Zwraca obiekt HTTPError. Tapestry wyświetli błąd HTTP po stronie klienta.
public Object onAction(){
return new HttpError(302, "The Error message);
}
Link Response- Zwraca bezpośrednio instancję łącza. Tapestry utworzy adres URL z obiektu Link i wyśle do klienta jako przekierowanie.
Stream Response - Zwraca StreamResponseobiekt. Tapestry wyśle strumień jako odpowiedź bezpośrednio do przeglądarki klienta. Służy do bezpośredniego generowania raportów i obrazów oraz wysyłania ich do klienta.
Url Response - Zwraca java.net.URLobiekt. Tapestry pobierze odpowiedni adres URL z obiektu i wyśle do klienta jako przekierowanie.
Object Response- Zwraca wartości inne niż podane powyżej. Tapestry spowoduje błąd.
Kontekst wydarzenia
Ogólnie rzecz biorąc, program obsługi zdarzeń może uzyskać informacje o kontekście za pomocą argumentów. Na przykład, jeśli informacje o kontekście to 3 typu int, procedura obsługi zdarzeń będzie miała wartość -
Object onActionFromTest(int id) {
}
Tapestry prawidłowo obsługuje informacje kontekstowe i dostarcza je metodom poprzez argumenty. Czasami Tapestry może nie być w stanie poprawnie sobie z tym poradzić ze względu na złożoność programowania. W tym czasie możemy uzyskać pełne informacje kontekstowe i sami je przetworzyć.
Object onActionFromEdit(EventContext context) {
if (context.getCount() > 0) {
this.selectedId = context.get(0);
} else {
alertManager.warn("Please select a document.");
return null;
}
}
Ten rozdział wyjaśnia wbudowane komponenty, które ma Tapestry, wraz z odpowiednimi przykładami. Tapestry obsługuje ponad 65 wbudowanych komponentów. Możesz także tworzyć komponenty niestandardowe. Omówmy szczegółowo niektóre z ważnych elementów.
Jeśli Component
Komponent if jest używany do warunkowego renderowania bloku. Stan jest sprawdzany za pomocą parametru testowego.
Utwórz stronę IfSample.java jak pokazano poniżej -
package com.example.MyFirstApplication.pages;
public class Ifsample {
public String getUser() {
return "user1";
}
}
Teraz utwórz odpowiedni plik szablonu w następujący sposób -
<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>
Żądanie strony spowoduje wyrenderowanie wyniku, jak pokazano poniżej.
Result - http: // localhost: 8080 / MyFirstApplication / ifsample
Chyba że i deleguj składnik
Plik unless componentjest przeciwieństwem komponentu if, który został omówiony powyżej. Podczas, gdydelegate componentnie wykonuje żadnego renderowania samodzielnie. Zamiast tego zwykle deleguje znaczniki do elementu blokowego. Chyba że i jeśli składniki mogą używać delegata i bloku do warunkowej zamiany zawartości dynamicznej.
Utwórz stronę Unless.java następująco.
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;
}
}
}
Teraz utwórz odpowiedni plik szablonu w następujący sposób -
<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>
Żądanie strony spowoduje wyrenderowanie wyniku, jak pokazano poniżej.
Result - http: // localhost: 8080 / MyFirstApplication / chyba
Komponent pętli
Składnik pętli jest podstawowym składnikiem do zapętlania elementów kolekcji i renderowania treści dla każdej wartości / iteracji.
Utwórz stronę pętli, jak pokazano poniżej -
Loop.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class Loop {
@Property
private int i;
}
Następnie utwórz odpowiedni szablon 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>
Składnik pętli ma następujące dwa parametry -
source- Źródło kolekcji. 1… 5 to rozwinięcie właściwości używane do tworzenia tablicy z określonym zakresem.
var- Zmienna renderowania. Służy do renderowania bieżącej wartości w treści szablonu.
Żądanie strony spowoduje wyrenderowanie wyniku, jak pokazano poniżej -
Składnik PageLink
Komponent PageLink służy do łączenia strony z jednej strony na inną. Utwórz stronę testową PageLink, jak poniżej -PageLink.java.
package com.example.MyFirstApplication.pages;
public class PageLink {
}
Następnie utwórz odpowiedni plik szablonu, jak pokazano poniżej -
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>
Komponent PageLink zawiera parametr strony, który powinien odnosić się do docelowej strony tapestry.
Result - http: // localhost: 8080 / myFirstApplication / pagelink
Składnik EventLink
Składnik EventLink wysyła nazwę zdarzenia i odpowiadający mu parametr za pośrednictwem adresu URL. Utwórz klasę strony EventsLink, jak pokazano poniżej.
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;
}
}
Następnie utwórz odpowiedni plik szablonu „EventsLink” w następujący sposób -
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 ma następujące dwa parametry -
Event- nazwa zdarzenia, które ma zostać wyzwolone w składniku EventLink. Domyślnie wskazuje na identyfikator komponentu.
Context- Jest to parametr opcjonalny. Określa kontekst odsyłacza.
Result - http: // localhost: 8080 / myFirstApplication / EventsLink
Po kliknięciu wartości licznika strona wyświetli nazwę zdarzenia w adresie URL, jak pokazano na poniższym zrzucie ekranu wyjściowego.
Składnik ActionLink
Składnik ActionLink jest podobny do składnika EventLink, ale wysyła tylko identyfikator składnika docelowego. Domyślna nazwa zdarzenia to akcja.
Utwórz stronę „ActivationLinks.java”, jak pokazano poniżej,
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;
}
}
Teraz utwórz odpowiedni plik szablonu, jak pokazano poniżej -
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>
Tutaj OnActionFromSub zostanie wywołana po kliknięciu składnika ActionLink.
Result - http: // localhost: 8080 / myFirstApplication / ActivationsLink
Alert Component
Okno dialogowe ostrzeżenia jest najczęściej używane do wysyłania ostrzeżeń do użytkowników. Na przykład, jeśli pole wejściowe wymaga jakiegoś obowiązkowego tekstu, ale użytkownik nie wprowadza żadnych danych wejściowych, wówczas w ramach walidacji można użyć pola ostrzegawczego, aby wysłać komunikat ostrzegawczy.
Utwórz stronę „Alerty”, jak pokazano w następującym programie.
Alerts.java
package com.example.MyFirstApplication.pages;
public class Alerts {
public String getUser() {
return "user1";
}
}
Następnie utwórz odpowiedni plik szablonu w następujący sposób -
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 ma trzy poziomy ważności, które są:
- Info
- Warn
- Error
Powyższy szablon jest tworzony za pomocą alertu informacyjnego. Jest zdefiniowany jakoalert-info. W zależności od potrzeb możesz utworzyć inne poziomy ważności.
Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/Alerts
Plik Form Componentsłuży do tworzenia formularza na stronie tkaniny do wprowadzania danych przez użytkownika. Formularz może zawierać pola tekstowe, pola daty, pola wyboru, opcje wyboru, przycisk przesyłania i inne.
W tym rozdziale szczegółowo omówiono niektóre z ważnych składników formularza.
Składnik pola wyboru
Składnik pola wyboru służy do wyboru między dwiema wzajemnie wykluczającymi się opcjami. Utwórz stronę za pomocą pola wyboru, jak pokazano poniżej -
Checkbox.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class Checkbox {
@Property
private boolean check1;
@Property
private boolean check2;
}
Teraz utwórz odpowiedni szablon Checkbox.tml jak pokazano poniżej -
<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>
Tutaj identyfikator parametru pola wyboru jest zgodny z odpowiednią wartością logiczną.
Result - Po zażądaniu strony, http: // localhost: 8080 / myFirstApplication / checkbox, daje następujący wynik.
Składnik TextField
Składnik TextField umożliwia użytkownikowi edycję pojedynczego wiersza tekstu. Utwórz stronęText jak pokazano niżej.
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;
}
Następnie utwórz odpowiedni szablon, jak pokazano poniżej - 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>
Tutaj strona Text zawiera właściwość o nazwie fname i lname. Dostęp do identyfikatorów składników uzyskuje się za pośrednictwem właściwości.
Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/Text
PasswordField Component
PasswordField to wyspecjalizowany wpis w polu tekstowym na hasło. Utwórz stronę Hasło, jak pokazano poniżej -
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;
}
Teraz utwórz odpowiedni plik szablonu, jak pokazano poniżej -
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>
Tutaj składnik PasswordField ma identyfikator parametru, który wskazuje na właściwość pwd. Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/Password
Składnik TextArea
Składnik TextArea to wielowierszowa kontrolka tekstu wejściowego. Utwórz stronę TxtArea, jak pokazano poniżej.
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;
}
Następnie utwórz odpowiedni plik szablonu, jak pokazano poniżej.
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>
W tym przypadku identyfikator parametru składnika TextArea wskazuje na właściwość „str”. Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/TxtArea**
Wybierz komponent
Komponent Wybierz zawiera rozwijaną listę opcji do wyboru. Utwórz stronę SelectOption, jak pokazano poniżej.
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
}
}
Następnie utwórz odpowiedni szablon w następujący sposób -
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>
Tutaj komponent Select ma dwa parametry -
Type - Typ właściwości to wyliczenie.
Id - Id wskazuje na właściwość Tapestry „color1”.
Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/SelectOption
RadioGroup Component
Składnik RadioGroup udostępnia grupę kontenerów dla składników Radio. Komponenty Radio i RadioGroup współpracują ze sobą, aby zaktualizować właściwość obiektu. Ten komponent powinien otaczać inne komponenty radiowe. Utwórz nową stronę „Radiobutton.java”, jak pokazano poniżej -
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;
}
Następnie utwórz odpowiedni plik szablonu, jak pokazano poniżej -
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>
W tym przypadku identyfikator komponentu RadioGroup jest powiązany z właściwością „wartość”. Żądanie strony da następujący wynik.
http://localhost:8080/myFirstApplication/Radiobutton
Prześlij składnik
Gdy użytkownik kliknie przycisk przesyłania, formularz jest wysyłany na adres podany w ustawieniu działania tagu. Utwórz stronęSubmitComponent jak pokazano niżej.
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.InjectPage;
public class SubmitComponent {
@InjectPage
private Index page1;
Object onSuccess() {
return page1;
}
}
Teraz utwórz odpowiedni plik szablonu, jak pokazano poniżej.
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>
Tutaj składnik Prześlij przesyła wartość do strony indeksu. Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/SubmitComponent
Walidacja formularza
Walidacja formularza odbywa się zwykle na serwerze po wprowadzeniu przez klienta wszystkich niezbędnych danych, a następnie przesłaniu formularza. Gdyby dane wprowadzone przez klienta były nieprawidłowe lub po prostu ich brakowało, serwer musiałby odesłać wszystkie dane z powrotem do klienta i zażądać ponownego przesłania formularza z poprawnymi informacjami.
Rozważmy następujący prosty przykład, aby zrozumieć proces walidacji.
Utwórz stronę Validate jak pokazano niżej.
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;
}
Teraz utwórz odpowiedni plik szablonu, jak pokazano poniżej.
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>
Walidacja formularza ma następujące istotne parametry -
Max - określa wartość maksymalną, np. = «Wartość maksymalna, 20».
MaxDate- definiuje maxDate, np. = «Data maksymalna, 09.06.2013». Podobnie możesz również przypisać MinDate.
MaxLength - maxLength np. = «Długość maksymalna, 80».
Min - minimum.
MinLength - Długość minimalna np. = «Długość minimalna, 2».
Email - Walidacja adresu e-mail, która wykorzystuje standardowe wyrażenie regularne e-mail ^ \ w [._ \ w] * \ w @ \ w [-._ \ w] * \ w \. \ W2,6 $ lub żadne.
Żądanie strony spowoduje następujący wynik -
http://localhost:8080/myFirstApplication/Validate
AJAX oznacza Asynchronous JavaScript and XML. Jest to technika tworzenia lepszych, szybszych i bardziej interaktywnych aplikacji internetowych przy pomocyXML, JSON, HTML, CSS, i JavaScript. AJAX umożliwia asynchroniczne wysyłanie i odbieranie danych bez przeładowywania strony internetowej, dzięki czemu jest szybki.
Komponent strefy
Składnik strefy służy do dostarczania treści (znaczników), a także położenia samej zawartości. Ciało komponentu strefy jest używane wewnętrznie przez Tapestry do generowania zawartości. Po wygenerowaniu dynamicznej zawartości Tapestry wyśle ją do klienta, ponownie przekaże dane we właściwym miejscu, wyzwoli i animuje HTML, aby przyciągnąć uwagę użytkownika.
Ten składnik Zone jest używany wraz ze składnikiem EventLink. EventLink ma opcję powiązania go z określoną strefą przy użyciu rozszerzeniat:zoneatrybuty. Po skonfigurowaniu strefy w EventLink, kliknięcie EventLink wyzwoli aktualizację strefy. Ponadto zdarzenia EventLink (refreshZone) mogą służyć do sterowania generowaniem danych dynamicznych.
Prosty przykład AJAX jest następujący -
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();
}
}
Wynik zostanie wyświetlony pod adresem: http: // localhost: 8080 / MyFirstApplication / AjaxZone
W tym rozdziale omówimy integrację BeanEditForm i Grid componentz Hibernate. Hibernacja jest zintegrowana z tapestry poprzez moduł hibernacji. Aby włączyć moduł hibernacji, dodaj zależność od hibernacji tapestry i opcjonalniehsqldb w pom.xmlplik. Teraz skonfiguruj hibernację za pomocąhibernate.cfg.xml plik umieszczony w katalogu głównym folderu zasobów.
pom.xml (częściowe)
<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>
Zobaczmy, jak stworzyć plik employee add page przy użyciu składnika BeanEditForm i employee list pageprzy użyciu składnika Siatka. Warstwa trwałości jest obsługiwana przez moduł Hibernate.
Utwórz klasę pracowniczą i udekoruj ją adnotacją @Entity. Następnie dodaj adnotację walidacyjną dla odpowiednich pól i adnotację związaną z hibernacją @Id i @GeneratedValue dla pola id. Utwórz także rodzaj jako typ wyliczenia.
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
}
Utwórz stronę z listą pracowników, ListEmployee.java w nowym folderze pracownik pod stronami i odpowiednim pliku szablonu ListEmployee.tml at /src/main/resources/pages/employeeteczka. Tapestry zapewnia krótki adres URL dla podfolderów, usuwając powtarzające się dane.
Na przykład, strona ListEmployee jest dostępna za pomocą zwykłego adresu URL - (/ worker / listemployee) i krótkiego adresu URL - (/ worker / list).
Wstrzyknij sesję hibernacji na stronę listy, używając adnotacji @Inject. Zdefiniuj właściwośćgetEmployeesna stronie listy i zapełnij ją pracownikami za pomocą wstrzykniętego obiektu sesji. Uzupełnij kod klasy pracownika, jak pokazano poniżej.
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();
}
}
Utwórz plik szablonu dla klasy ListEmployee. Szablon będzie miał dwa główne komponenty, którymi są -
PageLink - Utwórz stronę z łączem pracownika.
Grid- Służy do renderowania danych pracownika. Komponent siatki zawiera atrybuty źródeł do wprowadzenia listy pracowników oraz atrybuty uwzględniające pola do renderowania.
ListEmployee.tml (wymień wszystkich pracowników)
<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>
Utwórz plik szablonu tworzenia pracowników i dołącz komponent BeanEditForm. Komponent ma następujące atrybuty -
object - Zawiera źródło.
reorder - określa kolejność wyświetlanych pól.
submitlabel - Komunikat przycisku wysyłania formularza
Pełne kodowanie jest następujące -
<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>
Utwórz klasę tworzenia pracowników i dołącz sesję, właściwość pracownika, stronę listy (łącze nawigacyjne) i zdefiniuj zdarzenie OnSuccess (miejsce aktualizacji danych) komponentu. Dane sesji są utrwalane w bazie danych przy użyciu sesji hibernacji.
Pełne kodowanie jest następujące -
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;
}
}
Dodaj CreateEmployee.propertiesplik i dołącz wiadomość, która ma być używana w walidacji formularza. Kompletny kod wygląda następująco -
zip-regexp=^\\d{5}(-\\d{4})?$
zip-regexp-message = Zip Codes are five or nine digits. Example: 02134 or 901251655.
submit-label = Create Employee
Zrzut ekranu strony tworzenia pracowników i strony z listą pokazano poniżej -
Każda aplikacja internetowa powinna mieć jakiś sposób na przechowywanie pewnych danych użytkownika, takich jak obiekt użytkownika, preferencje użytkownika, itp. Na przykład w aplikacji koszyka wybrane elementy / produkty użytkownika powinny być zapisywane w tymczasowym wiadrze (koszyku), dopóki użytkownik nie wybierze kupić produkty. Możemy zapisać pozycje w bazie danych, ale będzie to zbyt drogie, ponieważ wszyscy użytkownicy nie będą kupować wybranych pozycji. Dlatego potrzebujemy tymczasowego rozwiązania do przechowywania / utrwalania przedmiotów. Apache Tapestry Zapewnia dwa sposoby utrwalania danych i są one -
- Dane strony trwałości
- Przechowywanie sesji
Obie mają swoje zalety i ograniczenia. Sprawdzimy to w kolejnych sekcjach.
Dane strony trwałości
Dane strony trwałości to prosta koncepcja utrwalania danych na jednej stronie między żądaniami i nazywana jest również Page Level Persistence. Można to zrobić za pomocą@Persist adnotacja.
@Persist
public int age;
Gdy pole zostanie opatrzone adnotacją @Persist, wartość pola zostanie utrwalona w żądaniu, a jeśli wartość zostanie zmieniona podczas żądania, zostanie odzwierciedlona przy następnym dostępie. Apache Tapestry zapewnia pięć typów strategii implementacji koncepcji @Persist. Są następujące -
Session Strategy - Dane są utrwalane przy użyciu sesji i jest to strategia domyślna.
Flash Strategy- Dane są również utrwalane przy użyciu Session, ale są one bardzo krótkotrwałe. Dane będą dostępne tylko w jednym kolejnym żądaniu.
@Persist(PersistenceConstants.FLASH)
private int age;
Client Strategy - Dane są utrwalane po stronie klienta, takie jak ciąg zapytania URL, ukryte pole w formularzu itp.
@Persist(PersistenceConstants.FLASH)
private int age;
Hibernate Entity Strategy- Dane są utrwalane przy użyciu modułu Hibernate jako jednostki. Jednostka zostanie zapisana w Hibernate, a jej odniesienie (nazwa klasy Java i jej klucz podstawowy) zostanie zapisane jako token wHttpSession. Jednostka zostanie przywrócona przy użyciu tokenu dostępnego w HttpSession.
@Persist(HibernatePersistenceConstants.ENTITY)
private Category category;
JPA Entity Strategy- Dane są utrwalane za pomocą modułu JPA. Będzie mógł przechowywać tylko Entity.
@Persist(JpaPersistenceConstants.ENTITY)
private User user;
Przechowywanie sesji
Przechowywanie sesji to zaawansowana koncepcja służąca do przechowywania danych, które muszą być dostępne na różnych stronach, takich jak dane w kreatorze wielu stron, dane logowania użytkownika itp. Magazyn sesji udostępnia dwie opcje, jedną do przechowywania złożonych obiektów, a drugą do przechowywania prostych wartości
Session Store Object - Służy do przechowywania złożonych obiektów.
Session Attributes - Służy do przechowywania prostych wartości.
Obiekt magazynu sesji (SSO)
SSO można utworzyć za pomocą @SessionStoreadnotacja. SSO zapisze obiekt przy użyciu typu obiektu. Na przykładCart Objectbędą przechowywane przy użyciu nazwy klasy koszyka jako tokenu. Tak więc każdy złożony obiekt może być przechowywany raz w aplikacji (jeden na użytkownika).
public class MySSOPage {
@SessionState
private ShoppingCart cart;
}
SSO jest wyspecjalizowanym sklepem i powinno być używane do przechowywania tylko złożonych / specjalnych obiektów. Proste typy danych mogą być również przechowywane przy użyciu SSO, ale przechowywanie prostych typów danych, takich jak String, powoduje, że przechowuje tylko jedną wartość „String” w aplikacji. Użycie pojedynczej wartości „String” w aplikacji jest po prostu niemożliwe. Możesz używać prostych typów danych, ponieważ Apache Tapestry zapewnia atrybuty sesji.
Atrybuty sesji
Atrybuty sesji umożliwiają przechowywanie danych według nazwy zamiast typu.
public class MyPage {
@SessionAttribute
private String loggedInUsername;
}
Domyślnie atrybuty sesji używają nazwy pola do odwoływania się do danych w sesji. Możemy zmienić nazwę odniesienia za pomocą parametru adnotacji, jak pokazano poniżej -
public class MyPage {
@SessionAttribute("loggedInUserName")
private String userName;
}
Jednym z głównych problemów związanych z używaniem nazwy jako odniesienia do sesji jest to, że możemy przypadkowo użyć tej samej nazwy w więcej niż jednej klasie / na jednej stronie. W takim przypadku przechowywane dane mogą się nieoczekiwanie zmienić. Aby rozwiązać ten problem, lepiej będzie użyć nazwy wraz z nazwą klasy / strony i nazwą pakietu, na przykładcom.myapp.pages.register.email, gdzie com.myapp.pages to nazwa pakietu, register to nazwa strony / klasy, a na końcu email to nazwa zmiennej (do zapisania).
W tym rozdziale omówimy szczegółowo kilka zaawansowanych funkcji Apache Tapestry.
Odwrócenie sterowania
Tapestry zapewnia wbudowaną bibliotekę Inversion of Control. Tapestry jest głęboko zintegrowany z IoC i wykorzystuje IoC we wszystkich swoich funkcjach. Konfiguracja Tapestry IoC jest oparta na samej Javie zamiast na XML, jak wiele innych kontenerów IoC. Moduły oparte na Tapestry IoC są pakowane do pliku JAR i po prostu umieszczane w ścieżce klas bez konfiguracji. Zastosowanie Tapestry IoC opiera się na lekkości, co oznacza -
Małe interfejsy z dwiema lub trzema metodami.
Małe metody z dwoma lub trzema parametrami.
Anonimowa komunikacja za pośrednictwem zdarzeń, a nie jawne wywołania metod.
Moduły
Moduł to sposób na rozszerzenie funkcjonalności aplikacji Tapestry. Tapestry ma zarówno wbudowane moduły, jak i dużą liczbę modułów innych firm. Hibernate jest jednym z gorących i bardzo przydatnych modułów dostarczonych przez Tapestry. Zawiera również moduły integrujące JMX, JPA, Spring Framework, JSR 303 Bean Validation, JSON itp. Niektóre z godnych uwagi modułów innych firm to -
- Tapestry-Cayenne
- Tapestry5-googleanalytics
- Gang of tapestry 5 - Tapestry5-HighCharts
- Gang of tapestry 5 - Tapestry5-jqPlot
- Gang of tapestry 5 - Tapestry5-Jquery
- Gang of tapestry 5 - Tapestry5-Jquery-mobile
- Gang of tapestry 5 - Tapestry5-Portlet
Wyjątki w czasie wykonywania
Jedną z najlepszych cech gobelinu jest Detailed Error Reporting. Tapestry pomaga programiście, zapewniając najnowocześniejsze raportowanie wyjątków. Raport wyjątków Tapestry to prosty HTML ze szczegółowymi informacjami. Każdy może łatwo zrozumieć raport. Tapestry pokazuje błąd w HTML, a także zapisuje wyjątek w postaci zwykłego tekstu z datą i godziną wystąpienia wyjątku. Pomoże to deweloperowi sprawdzić wyjątek również w środowisku produkcyjnym. Deweloper może mieć pewność, że naprawi wszelkie problemy, takie jak zepsute szablony, nieoczekiwane wartości null, niedopasowane żądania itp.
Ponowne ładowanie klas i szablonów na żywo
Tapestry automatycznie przeładuje szablony i klasy po modyfikacji. Ta funkcja umożliwia natychmiastowe odzwierciedlenie zmian aplikacji bez przechodzenia przez cykl kompilacji i testowania. Ponadto ta funkcja znacznie poprawia wydajność tworzenia aplikacji.
Rozważmy, że pakiet główny aplikacji to org.example.myfirstapp. Następnie klasy w poniższych ścieżkach są skanowane w celu ponownego załadowania.
- org.example.myfirstapp.pages
- org.example.myfirstapp.components
- org.example.myfirstapp.mixins
- org.example.myfirstapp.base
- org.example.myfirstapp.services
Przeładowywanie klas na żywo można wyłączyć, ustawiając tryb produkcyjny na true w AppModule.java.
configuration.add(SymbolicConstants.PRODUCTION_MODE,”false”);
Testów jednostkowych
Testowanie jednostkowe to technika, za pomocą której testowane są poszczególne strony i komponenty. Tapestry zapewnia łatwe opcje jednostkowego testowania stron i komponentów.
Testowanie jednostkowe strony: Tapestry zapewnia klasę PageTesteraby przetestować aplikację. Działa zarówno jako przeglądarka, jak i kontener serwletów. Renderuje stronę bez przeglądarki po stronie serwera, a wynikowy dokument można sprawdzić pod kątem prawidłowego renderowania. Rozważ prostą stronęHello, który renderuje hello, a tekst hello jest zawarty w elemencie HTML o identyfikatorze hello_id. Aby przetestować tę funkcję, możemy użyć PageTestera, jak pokazano poniżej -
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 zapewnia również opcję dołączania informacji kontekstowych, przesyłania formularzy, nawigacji po łączach itp. Oprócz renderowania strony.
Testowanie zintegrowane
Zintegrowane testowanie pomaga przetestować aplikację jako moduł zamiast sprawdzać poszczególne strony, jak w przypadku testów jednostkowych. W testowaniu zintegrowanym wiele modułów może być testowanych razem jako całość. Tapestry udostępnia małą bibliotekę o nazwieTapestry Test Utilitieszrobić zintegrowane testy. Ta biblioteka integruje się z narzędziem testowym Selenium do przeprowadzania testów. Biblioteka udostępnia klasę bazowąSeleniumTestCase, który uruchamia i zarządza serwerem Selenium, klientem Selenium i instancją Jetty.
Jeden z przykładów testów zintegrowanych jest następujący -
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");
}
}
Pulpit programistyczny
Pulpit programistyczny to domyślna strona używana do identyfikowania / rozwiązywania problemów w aplikacji. Pulpit nawigacyjny jest dostępny za pośrednictwem adresu URLhttp://localhost:8080/myfirstapp/core/t5dashboard. Pulpit pokazuje wszystkie strony, usługi i biblioteki komponentów dostępne w aplikacji.
Kompresja odpowiedzi
Tapestry automatycznie kompresuje odpowiedź za pomocą GZIP compressioni przesyłaj strumieniowo do klienta. Ta funkcja zmniejszy ruch w sieci i przyspieszy wyświetlanie strony. Kompresję można skonfigurować za pomocą symbolutapestry.min-gzip-sizew AppModule.java. Wartość domyślna to 100 bajtów. Tapestry skompresuje odpowiedź, gdy rozmiar odpowiedzi przekroczy 100 bajtów.
Bezpieczeństwo
Tapestry zapewnia wiele opcji zabezpieczania aplikacji przed znanymi lukami w zabezpieczeniach aplikacji internetowej. Niektóre z tych opcji są wymienione poniżej -
HTTPS - Strony z gobelinami można opatrzyć adnotacjami @Secure aby była bezpieczną stroną i dostępną dla https protocol tylko.
Page access control - Kontrolowanie dostępu do strony tylko dla określonego użytkownika.
White-Listed Page - Strony z gobelinem mogą być opatrzone adnotacją @WhitelistAccessOnly aby był dostępny tylko za pośrednictwem localhost.
Asset Security- Pod tapestry dostępne są tylko określone typy plików. Dostęp do innych można uzyskać tylko wtedy, gdy plikMD5 hash pliku.
Serialized Object Date - Tapestry integruje HMAC z zserializowanymi danymi obiektu Java i wysyła je do klienta, aby uniknąć manipulacji wiadomości.
Cross Site Request Forgery- Tapestry zapewnia 3 rd modułu partia o nazwie gobelin-CSRF-ochrony, aby zapobiec atakom CSRF żadnych.
Security Framework integration- Tapestry nie ogranicza się do pojedynczej implementacji uwierzytelniania / autoryzacji. Tapestry można zintegrować z dowolną popularną platformą uwierzytelniania.
Logowanie
Tapestry zapewnia szerokie wsparcie dla logowania, automatycznego rejestrowania postępu działania aplikacji. Tapestry używa de facto biblioteki logów Java,SLF4J. Adnotacja@Logmoże znajdować się w dowolnej metodzie składnika, aby wyemitować wejście i wyjście metody oraz ewentualny wyjątek. Ponadto obiekt rejestratora dostarczony przez Tapestry można wstrzyknąć do dowolnego komponentu przy użyciu@Inject adnotacja, jak pokazano poniżej -
public class MyPage {
@Inject
private Logger logger;
// . . .
void onSuccessFromForm() {
logger.info("Changes saved successfully");
}
@Log
void onValidateFromForm() {
// logic
}
}
Wreszcie, możemy teraz powiedzieć, że Apache Tapestry zapewnia najlepsze sposoby tworzenia zwięzłych, skalowalnych, łatwych w utrzymaniu, niezawodnych i obsługujących technologię Ajax aplikacji. Tapestry można zintegrować z dowolną aplikacją Java innej firmy. Może również pomóc w tworzeniu dużej aplikacji internetowej, ponieważ jest dość łatwy i szybki.