Apache Tapestry - Hướng dẫn nhanh
Apache Tapestry là một web framework mã nguồn mở được viết bằng Java. Nó là mộtcomponent based web framework. Các thành phần của tấm thảm là các Lớp Java. Chúng không được kế thừa từ một lớp cơ sở cụ thể của khung công tác cũng như không triển khai một giao diện và chúng chỉ là các POJO đơn giản (Đối tượng Java cũ thuần túy).
Tính năng quan trọng của Java được sử dụng bởi tấm thảm là Annotation. Các trang web của Tapestry được xây dựng bằng cách sử dụng một hoặc nhiều thành phần, mỗi thành phần có một mẫu dựa trên XML và lớp thành phần được trang trí bằng rất nhiều Chú thích của Tapestry. Tấm thảm có thể tạo ra bất kỳ thứ gì khác nhau, từ một ứng dụng web nhỏ, một trang đến một ứng dụng lớn bao gồm hàng trăm trang.
Lợi ích của tấm thảm
Một số lợi ích do tấm thảm mang lại là -
- Các ứng dụng web có khả năng mở rộng cao.
- API thích ứng.
- Khuôn khổ nhanh chóng và trưởng thành.
- Quản lý lưu trữ trạng thái liên tục.
- Tích hợp Inversion of Control.
Đặc điểm của tấm thảm
Tấm thảm có các tính năng sau:
- Tải lại lớp học trực tiếp
- Báo cáo ngoại lệ rõ ràng và chi tiết
- Cấu trúc tĩnh, các hành vi động.
- Sử dụng rộng rãi các đối tượng Java cũ thuần túy (POJO)
- Mã ít hơn, cung cấp nhiều hơn.
Tại sao Thảm tập?
Java đã có rất nhiều khuôn khổ web như JSP, Struts, v.v., Vậy tại sao chúng ta cần một khuôn khổ khác? Hầu hết các Java Web Framework ngày nay đều phức tạp và có quá trình học tập khó khăn. Chúng đã lỗi thời và yêu cầu chu trình biên dịch, kiểm tra và triển khai cho mỗi bản cập nhật.
Mặt khác, Tapestry cung cấp một cách tiếp cận hiện đại để lập trình ứng dụng web bằng cách cung cấp live class reloading. Trong khi các khung công tác khác đang giới thiệu rất nhiều giao diện, lớp trừu tượng và lớp cơ sở, Tapestry chỉ giới thiệu một tập hợp nhỏ các chú thích và vẫn cung cấp khả năng viết ứng dụng lớn với hỗ trợ AJAX phong phú.
Tapestry cố gắng sử dụng các tính năng có sẵn của Java càng nhiều càng tốt. Ví dụ, tất cả các trang Tapestry chỉ đơn giản là POJO. Nó không bắt buộc bất kỳ giao diện tùy chỉnh hoặc lớp cơ sở nào để viết ứng dụng. Thay vào đó, nó sử dụng Annotation (một tùy chọn trọng lượng nhẹ để mở rộng chức năng của một lớp Java) để cung cấp các tính năng. Nó dựa trên trận chiến đã được thử nghiệmJava Servlet APIvà được triển khai như một Bộ lọc Servlet. Nó cung cấp một khía cạnh mới cho ứng dụng web và lập trình khá đơn giản, linh hoạt, dễ hiểu và mạnh mẽ.
Quy trình làm việc
Hãy để chúng tôi thảo luận về trình tự hành động diễn ra khi một trang thảm được yêu cầu.
Step 1 - Sự Java Servletnhận được yêu cầu trang. Java Servlet này được cấu hình theo cách mà yêu cầu đến sẽ được chuyển tiếp đến tấm thảm. Cấu hình được thực hiện trongweb.xmlnhư được chỉ định trong chương trình sau. Bộ lọc và thẻ Ánh xạ bộ lọc chuyển hướng tất cả yêu cầu đến Bộ lọc Tapestry .
<!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 - Sự Tapestry Filter gọi cho HttpServletRequestHandler Dịch vụ của nó Service() phương pháp.
Step 3 - HttpServletRequestHandler lưu trữ yêu cầu và phản hồi trong RequestGlobals. Nó cũng bao bọc yêu cầu và phản hồi như một đối tượng Yêu cầu và Phản hồi và gửi nó tới RequestHandler.
Step 4 - Sự RequestHandler là một sự trừu tượng trên HttpServletRequestcủa API Servlet. Một số tính năng nổi bật của tấm thảm được thực hiện trongRequestHandlerphần. Tính năng của tấm thảm có thể được mở rộng bằng cách viết một bộ lọc trong RequestHandler. RequestHandler cung cấp một số bộ lọc tích hợp, bao gồm:
CheckForUpdates Filter- Chịu trách nhiệm tải lại lớp trực tiếp. Bộ lọc này kiểm tra các lớp java để tìm các thay đổi và cập nhật ứng dụng khi cần thiết.
Localization Filter - Xác định vị trí của người dùng và cung cấp hỗ trợ bản địa hóa cho ứng dụng.
StaticFiles Filter- Xác định yêu cầu tĩnh và hủy bỏ quá trình. Khi quá trình bị hủy bỏ, Java Servlet sẽ kiểm soát và xử lý yêu cầu.
Error Filter - Nắm bắt các ngoại lệ không cần thiết và trình bày trang báo cáo ngoại lệ.
RequestHandler cũng sửa đổi và lưu trữ yêu cầu và phản hồi trong RequestQlobals và gọi ra dịch vụ MasterDispatcher.
Step 5 - Sự MasterDispatcherchịu trách nhiệm kết xuất trang bằng cách gọi một số người điều phối là một đơn đặt hàng cụ thể. Bốn điều phối viên chính được gọi bởi MasterDispatcher như sau:
RootPath Dispatcher - Nó nhận ra đường dẫn gốc “/” của yêu cầu và hiển thị giống như trang Bắt đầu.
Asset Dispatcher - Nó nhận ra yêu cầu nội dung (tài sản Java) bằng cách kiểm tra mẫu url / tài sản / và gửi nội dung được yêu cầu dưới dạng luồng byte.
PageRender Dispatcher- Hàng loạt hoạt động của tấm thảm được thực hiện trong PageRender Dispatcher và điều phối thành phần điều phối tiếp theo. Người điều phối này nhận ra trang cụ thể của yêu cầu đó và bối cảnh kích hoạt của nó (thông tin bổ sung). Sau đó, nó hiển thị trang cụ thể đó và gửi nó cho khách hàng. Ví dụ: nếu url yêu cầu là / product / 12123434, người điều phối sẽ kiểm tra xem có lớp nào có tên product / 12123434 hay không. Nếu được tìm thấy, nó gọi lớp product / 12123434, tạo phản hồi và gửi cho khách hàng. Nếu không, nó sẽ kiểm tra loại sản phẩm. Nếu được tìm thấy, nó sẽ gọi lớp sản phẩm với thông tin bổ sung 121234434, tạo phản hồi và gửi cho khách hàng. Thông tin bổ sung này được gọi là Bối cảnh kích hoạt. Nếu không tìm thấy lớp nào, nó chỉ cần chuyển tiếp yêu cầu tới Component Dispatcher.
Component Dispatcher- Trình điều phối thành phần đối sánh URL của trang với mẫu - / <class_name> / <component_id>: <event_type> / <activation_context>. Ví dụ: / product / grid: sort / asc đại diện cho lớp sản phẩm, thành phần lưới, loại sortevent và ngữ cảnh kích hoạt asc. Ở đây, event_type là tùy chọn và nếu không có sự kiện nào được cung cấp, hành động loại sự kiện mặc định sẽ được kích hoạt. Thông thường, phản hồi của bộ điều phối thành phần là gửi một chuyển hướng đến máy khách. Hầu hết, chuyển hướng sẽ khớp với PageRender Dispatcher trong yêu cầu tiếp theo và phản hồi thích hợp sẽ được gửi cho khách hàng.
Trong chương này, chúng tôi sẽ thảo luận về cách cài đặt Tapestry trên máy của chúng tôi.
Điều kiện tiên quyết
Sự phụ thuộc duy nhất của tấm thảm là Core Java. Tấm thảm được phát triển độc lập mà không sử dụng bất kỳ thư viện / khuôn khổ nào của bên thứ ba. Ngay cả thư viện IoC được sử dụng bởi tấm thảm cũng được phát triển từ đầu. Ứng dụng web được viết bằng tấm thảm có thể được xây dựng và triển khai từ chính bảng điều khiển.
Chúng ta có thể sử dụng Maven, Eclipse và Jettyđể cải thiện trải nghiệm phát triển. Maven cung cấp các mẫu ứng dụng khởi động nhanh và các tùy chọn để lưu trữ ứng dụng trong Jetty, máy chủ phát triển de-facto của Java. Eclipse cung cấp các tính năng quản lý dự án mở rộng và tích hợp tốt với maven.
Một sự phát triển ứng dụng thảm trang trí lý tưởng cần những điều sau:
- Java 1.6 trở lên
- Apache Maven
- IDE Eclipse
- Máy chủ Jetty
Xác minh cài đặt Maven
Hy vọng rằng bạn đã cài đặt Maven trên máy của mình. Để xác minh cài đặt Maven, hãy nhập lệnh dưới đây:
mvn --version
Bạn có thể thấy phản hồi như hình dưới đây -
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"
Nếu Maven chưa được cài đặt, hãy tải xuống và cài đặt phiên bản maven mới nhất bằng cách truy cập trang web của Maven .
Tải xuống tấm thảm
Phiên bản mới nhất của tấm thảm là 5.4 và có thể được tải xuống từ trang web của Tapestry . Nó là đủ để tải xuống gói nhị phân . Nếu chúng tôi sử dụng Mẫu bắt đầu nhanh Maven, thì không cần thiết phải tải xuống Tapestry một cách riêng biệt. Maven tự động tải xuống các lọ đựng Tapestry cần thiết và định cấu hình ứng dụng. Chúng ta sẽ thảo luận về cách tạo một Ứng dụng Tấm thảm cơ bản bằng Maven trong chương tiếp theo.
Sau khi cài đặt Tapestry, chúng ta hãy tạo một dự án ban đầu mới bằng Maven như hình dưới đây -
$ mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org
Bạn có thể thấy phản hồi như hình dưới đây -
[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)
Sau khi Maven xây dựng tất cả các hoạt động, hãy chọn nguyên mẫu để tạo Tapestry 5 QuickStart dự án như sau -
Choose archetype -
https://tapestry.apache.org → org.apache.tapestry: khởi động nhanh (Dự án khởi động nhanh Tapestry 5)
https://tapestry.apache.org → org.apache.tapestry: tapestry-archetype (Tapestry 4.1.6 Archetype)
Chọn một số hoặc áp dụng bộ lọc (định dạng: [groupId:] artistId, có phân biệt chữ hoa chữ thường):: 1
Bây giờ bạn sẽ nhận được một phản hồi giống như những gì được hiển thị bên dưới -
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
Trích xuất số phiên bản QuickStart như sau:
Choose a number: 5: 5
Ở đây, dự án QuickStart lấy phiên bản cho tùy chọn 5, “5.4.1”. Bây giờ, kiểu mẫu của Tapestry hỏi từng thông tin sau như sau:
5.1 groupId - Xác định giá trị cho thuộc tính 'groupId':: com.example
5.2 artifactId - Xác định giá trị cho thuộc tính 'ArtifactId':: Myapp
5.3 version - Xác định giá trị cho thuộc tính 'phiên bản': 1.0-SNAPSHOT::
5.4 package name - Xác định giá trị cho thuộc tính 'package': com.example:: com.example.Myapp
Bây giờ màn hình của bạn yêu cầu xác nhận từ bạn -
Xác nhận cấu hình thuộc tính -
groupId - com.example
artifactId - Myapp
version - 1.0-SNAPSHOT
package - com.example.Myapp
Xác minh tất cả các thuộc tính và xác nhận các thay đổi bằng cách sử dụng tùy chọn được hiển thị bên dưới -
Y: : Y
Bạn sẽ thấy màn hình như hình dưới đây.
[INFO] ---------------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: quickstart:5.4.1
[INFO] ---------------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: Myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.example.Myapp
[INFO] Parameter: packageInPathFormat, Value: com/example/Myapp
[INFO] Parameter: package, Value: com.example.Myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: Myapp
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/java
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/main/webapp
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/main/resources/com/
example/Myapp
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/resource
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/conf
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/site
[INFO] project created from Archetype in dir: /Users/workspace/tapestry/Myapp
[INFO] ---------------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ---------------------------------------------------------------------------------
[INFO] Total time: 11:28 min
[INFO] Finished at: 2016-09-14T00:47:23+05:30
[INFO] Final Memory: 14M/142M
[INFO] ---------------------------------------------------------------------------------
Đến đây, bạn đã xây dựng thành công dự án Tapestry Quick Start. Di chuyển đến vị trí của cái mới được tạoMyapp thư mục với lệnh sau và bắt đầu viết mã.
cd Myapp
Chạy ứng dụng
Để chạy dự án khung, hãy sử dụng lệnh sau.
mvn jetty:run -Dtapestry.execution-mode=development
Bạn sẽ có một màn hình như thế này,
[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
Hiện tại, chúng tôi đã tạo một dự án Bắt đầu nhanh cơ bản trong Tapestry. Để xem ứng dụng đang chạy trong trình duyệt web, chỉ cần nhập URL sau vào thanh địa chỉ và nhấn enter -
https://localhost:8080/myapp
Đây, myapp là tên của ứng dụng và cổng mặc định của ứng dụng ở chế độ phát triển là 8080.
Sử dụng Eclipse
Trong chương trước, chúng ta đã thảo luận về cách tạo ứng dụng Tapestry Quick Start trong CLI. Chương này giải thích về cách tạo ứng dụng khung trongEclipse IDE.
Hãy để chúng tôi sử dụng mẫu Maven để tạo ứng dụng khung. Để cấu hình một ứng dụng mới, bạn có thể làm theo các bước dưới đây.
Bước 1: Mở IDE Eclipse
Mở Eclipse của bạn và chọn tùy chọn Tệp → Mới → Dự án… → như được hiển thị trong ảnh chụp màn hình sau.
Bây giờ, hãy chọn tùy chọn Maven → Maven project.
Note - Nếu Maven chưa được cấu hình thì hãy cấu hình và tạo một dự án.
Sau khi chọn dự án Maven, nhấp vào Tiếp theo và một lần nữa nhấp vào nút Tiếp theo.
Sau đó, bạn sẽ nhận được một màn hình nơi bạn nên chọn tùy chọn cấu hình. Khi nó được cấu hình, bạn sẽ nhận được màn hình sau.
Bước 2: Cấu hình danh mục
Sau khi bước đầu tiên được thực hiện, bạn nên nhấp vào Add Remote Catalog. Sau đó, thêm các thay đổi sau như được hiển thị trong ảnh chụp màn hình sau.
Bây giờ, Apache Tapestry Catalog được thêm vào. Sau đó, chọn tùy chọn bộ lọc org.apache.tapestry khởi động nhanh 5.4.1 như hình dưới đây.
Sau đó nhấn Next và màn hình sau sẽ xuất hiện.
Bước 3: Định cấu hình GroupId, ArtifactId, phiên bản và gói
Thêm các thay đổi sau vào cấu hình Danh mục trang phục.
Sau đó nhấp vào nút Kết thúc, bây giờ chúng ta đã tạo ứng dụng bộ xương đầu tiên. Lần đầu tiên bạn sử dụng Maven, việc tạo dự án có thể mất một lúc vì Maven tải xuống nhiều phụ thuộc JAR cho Maven, Jetty và Tapestry. Sau khi hoàn tất Maven, bạn sẽ thấy một thư mục mới, MyFirstApplication trong dạng xem Package Explorer của bạn.
Bước 4: Chạy ứng dụng bằng máy chủ Jetty
Bạn có thể sử dụng Maven để chạy trực tiếp Jetty. Nhấp chuột phải vào dự án MyFirstApplication trong dạng xem Package Explorer của bạn và chọn Run As → Maven Build… bạn sẽ thấy màn hình hiển thị bên dưới.
Trong hộp thoại cấu hình, hãy nhập tùy chọn mục tiêu là “cầu cảng: chạy”, sau đó nhấp vào nút Chạy.
Sau khi Jetty được khởi chạy, bạn sẽ thấy màn hình sau trong bảng điều khiển của mình.
Bước 5: Chạy trong trình duyệt web
Nhập URL sau để chạy ứng dụng trong trình duyệt web -
https://loclhost:8080/MyFirstApplication
Bước 6: Dừng máy chủ Jetty
Để dừng máy chủ Jetty, hãy nhấp vào biểu tượng hình vuông màu đỏ trong bảng điều khiển của bạn như hình bên dưới.
Đây là bố cục của mã nguồn được tạo bởi Maven Quickstart CLI. Ngoài ra, đây là bố cục được đề xuất của một Ứng dụng Thảm tập tiêu chuẩn.
├── 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
Bố cục mặc định được sắp xếp giống như WAR Internal File Format. Sử dụng định dạng WAR giúp chạy ứng dụng mà không cần đóng gói và triển khai. Bố cục này chỉ là một gợi ý, nhưng ứng dụng có thể được sắp xếp ở bất kỳ định dạng nào, nếu nó được đóng gói thành định dạng WAR thích hợp trong khi triển khai.
Mã nguồn có thể được chia thành bốn phần chính sau đây.
Java Code - Tất cả các mã nguồn java được đặt dưới /src/main/javathư mục. Các lớp của trang Tapestry được đặt trong thư mục “Pages” và các lớp thành phần của Tapestry được đặt trong thư mục component. Các lớp dịch vụ tấm thảm được đặt trong thư mục dịch vụ.
ClassPath Resources- Trong Tapestry, hầu hết các lớp đều có tài nguyên liên kết (Mẫu XML, tệp JavaScript, v.v.). Các tài nguyên này được đặt dưới/src/main/resourcesthư mục. Các lớp trang Tapestry có các tài nguyên liên quan trong thư mục “Pages” và các lớp thành phần Tapestry có các tài nguyên liên kết trong thư mục Components. Các tài nguyên này được đóng gói thànhWEB-INF/classes thư mục của WAR.
Context Resources - Chúng là các tài nguyên tĩnh của một ứng dụng web như Hình ảnh, Trang định kiểu và Thư viện JavaScript / Modules. They are usually placed under the /src/main/webapp thư mục và chúng được gọi là Context Resources. Ngoài ra, tệp mô tả ứng dụng web (của Java Servlet), web.xml được đặt dướiWEB-INF thư mục tài nguyên ngữ cảnh.
Testing Code - Đây là các tệp tùy chọn được sử dụng để kiểm tra ứng dụng và được đặt dưới src/test/java và src/test/Thư mục Tài nguyên. Chúng không được đóng gói thành WAR.
Apache Tapestry sau Convention over Configurationtrong mọi khía cạnh của lập trình. Mọi tính năng của khung đều có một quy ước mặc định hợp lý.
Ví dụ, như chúng ta đã học trong chương Bố cục Dự án, tất cả các trang cần được đặt trong /src/main/java/«package_path»/pages/ thư mục được coi là Trang Tấm thảm.
Theo một nghĩa khác, không cần phải định cấu hình một Lớp Java cụ thể làm các Trang Tapestry. Chỉ cần đặt lớp học ở một vị trí được xác định trước là đủ. Trong một số trường hợp, thật kỳ quặc khi tuân theo quy ước mặc định của Tấm thảm.
Ví dụ, thành phần Tapestry có thể có một phương thức setupRendersẽ được kích hoạt khi bắt đầu giai đoạn kết xuất. Một nhà phát triển có thể muốn sử dụng tên riêng của họ, nóiinitializeValue. Trong tình huống này, Tapestry cung cấpAnnotation để ghi đè các quy ước như được hiển thị trong khối mã sau.
void setupRender() {
// initialize component
}
@SetupRender
void initializeValue() {
// initialize component
}
Cả hai cách lập trình đều hợp lệ trong Tapestry. Tóm lại, cấu hình mặc định của Tapestry khá tối thiểu. ChỉApache Tapestry Filter (Java Servlet Filter) cần được cấu hình trong “Web.xml” để ứng dụng hoạt động bình thường.
Tấm thảm cung cấp một cách khác để định cấu hình ứng dụng và nó được gọi là AppModule.java.
Chú thích là một tính năng rất quan trọng được Tapestry khai thác để đơn giản hóa việc phát triển ứng dụng web. Tapestry cung cấp rất nhiều Chú thích tùy chỉnh. Nó có chú thích cho các lớp, phương thức và trường thành viên. Như đã thảo luận trong phần trước, Chú thích cũng có thể được sử dụng để ghi đè quy ước mặc định của một đối tượng địa lý. Các chú thích của tấm thảm được nhóm thành bốn loại chính và chúng như sau.
Chú thích thành phần
Được sử dụng trong các lớp Pages, Components và Mixins. Một số chú thích hữu ích là -
@Property- Nó có thể áp dụng cho các lĩnh vực. Được sử dụng để chuyển đổi một trường thành Thuộc tính tấm thảm.
@Parameter- Nó có thể áp dụng cho các lĩnh vực. Được sử dụng để chỉ định một trường làm tham số của một thành phần.
@Environmental- Nó có thể áp dụng cho các lĩnh vực. Được sử dụng để chia sẻ một trường riêng giữa các thành phần khác nhau.
@import- Nó có thể áp dụng cho các lớp và trường. Được sử dụng để bao gồm Nội dung, CSS và JavaScript.
@Path - Được sử dụng cùng với chú thích @Inject để đưa Nội dung vào dựa trên một đường dẫn.
@Log- Nó có thể áp dụng cho các lớp và trường. Được sử dụng cho mục đích gỡ lỗi. Có thể được sử dụng thông tin sự kiện của thành phần phát ra như bắt đầu sự kiện, kết thúc sự kiện, v.v.
Chú thích IoC
Dùng để tiêm các đối tượng vào IoC Container. Một số chú thích hữu ích là -
@Inject- Nó có thể áp dụng cho các lĩnh vực. Được sử dụng để đánh dấu các thông số cần được đưa vào thùng chứa IoC. Nó đánh dấu các trường cần được đưa vào các thành phần.
@Value- Nó có thể áp dụng cho các lĩnh vực. Được sử dụng cùng với chú thích @inject để đưa vào một giá trị chữ thay vì một dịch vụ (đó là hành vi mặc định của chú thích @inject).
Chú thích cho các lớp nắm giữ dữ liệu
Nó được sử dụng để chỉ định thông tin cụ thể của thành phần trong một lớp (thường là các mô hình hoặc các lớp giữ dữ liệu) cho các thành phần cấp cao như
Grid (được sử dụng để tạo dữ liệu dạng bảng nâng cao như báo cáo, thư viện, v.v.)
BeanEditForm (Dùng để tạo biểu mẫu nâng cao)
Hibernate (Được sử dụng trong truy cập cơ sở dữ liệu nâng cao), v.v.
Các Chú thích này được tổng hợp và đóng gói vào một lọ riêng biệt mà không phụ thuộc vào tấm thảm. Một số chú thích là -
@DataType- Nó được sử dụng để chỉ định kiểu dữ liệu của trường. Thành phần tấm thảm có thể sử dụng thông tin này để tạo thiết kế hoặc đánh dấu trong lớp trình bày.
@Validate - Nó được sử dụng để chỉ định quy tắc xác thực cho một trường.
Những phân cách này cho phép Ứng dụng Tapestry sử dụng Multi-Tier Design.
Ứng dụng Tapestry đơn giản là một tập hợp các Trang Tapestry. Chúng làm việc cùng nhau để tạo thành một Ứng dụng Web được xác định rõ ràng. Mỗi Trang sẽ có một Mẫu XML tương ứng và Zero, một hoặc nhiều Thành phần. Trang và Thành phần giống nhau ngoại trừ Trang là thành phần gốc và thường được tạo bởi nhà phát triển ứng dụng.
Components are children of the root Pagecomponent. Tấm thảm có rất nhiều thành phần tích hợp và có tùy chọn để tạo thành phần tùy chỉnh.
Các trang
Như đã thảo luận trước đó, Pages đang xây dựng các khối của một Ứng dụng Tapestry. Các trang là POJO đơn giản, được đặt dưới -/src/main/java/«package_path»/pages/thư mục. Mỗi Trang sẽ có mộtXML Template và vị trí mặc định của nó là - /src/main/resources/«package_name»/pages/.
Bạn có thể thấy ở đây rằng cấu trúc đường dẫn tương tự cho Trang và Mẫu ngoại trừ việc mẫu nằm trong Resource Folder.
Ví dụ: trang đăng ký người dùng trong ứng dụng Tapestry có tên gói - com.example.MyFirstApplication sẽ có các tệp Trang và Mẫu sau:
Java Class -
/src/main/java/com/example/MyFirstApplication/pages/index.java
XML Template -
/src/main/resources/com/example/MyFirstApplication/pages/index.tml
Hãy để chúng tôi tạo ra một Hello Worldtrang. Đầu tiên, chúng ta cần tạoJava Class tại - /src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java ”.
package com.example.MyFirstApplication.pages;
public class HelloWorld {
}
Sau đó, tạo một Mẫu XML tại -
“/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>
Bây giờ, trang này có thể được truy cập tại https://localhost:8080/myapp/helloworld. Đây là một trang thảm đơn giản. Tapestry cung cấp nhiều tính năng hơn để phát triển các trang web động, mà chúng ta sẽ thảo luận trong các chương sau.
Chúng ta hãy xem xét Mẫu XML của Tapestry trong phần này. Mẫu XML là một tài liệu XML được định dạng tốt. Lớp trình bày (Giao diện Người dùng) của một Trang là Mẫu XML. Mẫu XML có đánh dấu HTML bình thường ngoài các mục được cung cấp bên dưới -
- Vùng tên tấm thảm
- Expansions
- Elements
- Components
Bây giờ chúng ta hãy thảo luận chi tiết về chúng.
Vùng tên tấm thảm
Tapestry Không gian tên không là gì khác ngoài Không gian tên XML. Không gian tên phải được xác định trong phần tử gốc của mẫu. Nó được sử dụng để bao gồm các Thành phần Tapestry và thông tin liên quan đến thành phần trong Mẫu. Các không gian tên được sử dụng phổ biến nhất như sau:
xmlns: t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” - Nó được sử dụng để xác định các Phần tử, Thành phần và Thuộc tính của Tapestry.
xmlns: p = “tapestry: tham số” - Nó được sử dụng để truyền các đoạn mã tùy ý cho các thành phần.
Ví dụ về Tapestry Namespace như sau:
<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>
Mở rộng
Mở rộng là phương pháp đơn giản và hiệu quả để thay đổi động Mẫu XML trong giai đoạn kết xuất của Trang. Mở rộng sử dụng cú pháp $ {<name>}. Có nhiều tùy chọn để thể hiện sự mở rộng trong Mẫu XML. Hãy để chúng tôi xem một số tùy chọn thường được sử dụng nhất -
Mở rộng tài sản
Nó ánh xạ thuộc tính được xác định trong lớp Trang tương ứng. Nó tuân theo Đặc tả Java Bean để định nghĩa thuộc tính trong một lớp Java. Nó tiến thêm một bước nữa bằng cách bỏ qua các trường hợp tên tài sản. Hãy để chúng tôi thay đổi ví dụ “Hello World” bằng cách sử dụng mở rộng thuộc tính. Khối mã sau là lớp Trang đã sửa đổi.
package com.example.MyFirstApplication.pages;
public class HelloWorld {
// Java Bean Property
public String getName {
return "World!";
}
}
Sau đó, thay đổi Mẫu XML tương ứng như hình dưới đây.
<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>
Ở đây, chúng tôi đã xác định name như Java Bean Property trong lớp Trang và xử lý động nó trong Mẫu XML bằng cách sử dụng mở rộng ${name}.
Mở rộng tin nhắn
Mỗi lớp Trang có thể có hoặc không có tệp Thuộc tính được liên kết - «page_name».propertiestrong thư mục tài nguyên. Tệp thuộc tính là tệp văn bản thuần túy có một cặp khóa / giá trị (thông báo) trên mỗi dòng. Hãy để chúng tôi tạo tệp thuộc tính cho Trang HelloWorld tại -
“/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties” và thêm thông báo “Lời chào”.
Greeting = Hello
Các Greeting có thể được sử dụng trong Mẫu XML dưới dạng ${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>
Thành phần
Tấm thảm có một tập hợp nhỏ các phần tử được sử dụng trong Mẫu XML. Các phần tử là các thẻ xác định trước được xác định trong không gian tên Tapestry -
https://tapestry.apache.org/schema/tapestry_5_4.xsd
Mỗi phần tử được tạo ra cho một mục đích cụ thể. Các yếu tố thảm có sẵn như sau:
<t: body>
Khi hai thành phần được lồng vào nhau, mẫu của thành phần mẹ có thể phải bọc mẫu của thành phần con. Phần tử <t: body> hữu ích trong trường hợp này. Một trong những cách sử dụng <t: body> là trong Bố cục Mẫu.
Nói chung, Giao diện Người dùng của một ứng dụng web sẽ có Đầu trang, Chân trang, Menu chung, v.v. Những mục chung này được định nghĩa trong Mẫu XML và nó được gọi là Bố cục Mẫu hoặc Thành phần Bố cục. Trong Tapestry, nó cần được tạo bởi một nhà phát triển ứng dụng. Thành phần Bố cục chỉ là một thành phần khác và được đặt trong thư mục thành phần, có đường dẫn sau:src/main/«java|resources»/«package_name»/components.
Hãy để chúng tôi tạo một thành phần bố cục đơn giản được gọi là MyCustomLayout. Mã cho MyCustomLayout như sau:
<!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;
}
Trong lớp thành phần MyCustomLayout, chúng tôi đã khai báo trường tiêu đề và bằng cách sử dụng chú thích, chúng tôi đã đặt nó trở thành trường bắt buộc. Bây giờ, hãy thay đổi mẫu HelloWorld.html để sử dụng bố cục tùy chỉnh của chúng tôi như được hiển thị trong khối mã bên dưới.
<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>
Ở đây chúng ta có thể thấy rằng Mẫu XML không có thẻ head và body. Tapestry sẽ thu thập các chi tiết này từ thành phần bố cục và <t: body> của thành phần bố cục sẽ được thay thế bằng Mẫu HelloWorld. Sau khi mọi thứ hoàn tất, Tapestry sẽ phát ra đánh dấu tương tự như được chỉ định bên dưới:
<!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>
Các bố cục có thể được lồng vào nhau. Ví dụ: chúng tôi có thể mở rộng bố cục tùy chỉnh của mình bằng cách bao gồm chức năng quản trị và sử dụng nó cho phần quản trị như được chỉ định bên dưới.
<html t:type = "MyCommonLayout"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<div><!-- Admin related items --><div>
<t:body/>
</html>
<t: container>
<T: container> là một phần tử cấp cao nhất và bao gồm một không gian tên tấm thảm. Điều này được sử dụng để chỉ định phần động của một thành phần.
Ví dụ: một thành phần lưới có thể cần một mẫu để xác định cách hiển thị các hàng của nó - tr (và cột td) trong bảng 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> là phần giữ chỗ cho phần động trong mẫu. Nói chung, phần tử khối không hiển thị. Chỉ, các thành phần được xác định trong mẫu sử dụng phần tử khối. Các thành phần sẽ đưa dữ liệu động vào phần tử khối và hiển thị nó. Một trong những trường hợp sử dụng phổ biến làAJAX.
Phần tử khối cung cấp vị trí và đánh dấu chính xác cho dữ liệu động sẽ được hiển thị. Mọi phần tử khối phải có một Thuộc tính Java tương ứng. Chỉ khi đó nó mới có thể được hiển thị động. Id của phần tử khối phải tuân theo các quy tắc nhận dạng biến Java. Mẫu một phần được cung cấp bên dưới.
@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>
Phần tử <t: content> được sử dụng để chỉ định nội dung thực tế của mẫu. Nói chung, tất cả các đánh dấu được coi là một phần của mẫu. Nếu <t: content> được chỉ định, chỉ đánh dấu bên trong nó sẽ được xem xét. Tính năng này được các nhà thiết kế sử dụng để thiết kế một trang không có thành phần bố cục.
<t: remove>
<T: remove> chỉ đối lập với phần tử nội dung. Đánh dấu bên trong phần tử loại bỏ không được coi là một phần của mẫu. Nó chỉ có thể được sử dụng cho các bình luận của máy chủ và cho các mục đích thiết kế.
Tài sản
Nội dung là các tệp tài nguyên tĩnh như biểu định kiểu, hình ảnh và tệp JavaScript. Nói chung, nội dung được đặt trong thư mục gốc của ứng dụng web/src/main/webapp.
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tấm thảm cũng xử lý các tệp được lưu trữ trong Java Classpathdưới dạng Tài sản. Tapestry cung cấp các tùy chọn nâng cao để đưa Nội dung vào mẫu thông qua tùy chọn mở rộng.
Context - Tùy chọn để có được nội dung có sẵn trong ngữ cảnh web.
<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>
asset- Các thành phần thường lưu trữ các tài sản riêng của nó bên trong tệp jar cùng với các lớp Java. Bắt đầu từ Tapestry 5.4, đường dẫn tiêu chuẩn để lưu trữ nội dung trong classpath làMETA-INF/assets. Đối với thư viện, đường dẫn chuẩn để lưu trữ nội dung làMETA-INF/assets/«library_name»/. asset: cũng có thể gọi context: mở rộng để lấy nội dung từ ngữ cảnh web.
<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>
Nội dung có thể được đưa vào Trang Tapestry hoặc Thành phần bằng cách sử dụng chú thích Inject và Path. Tham số cho chú thích đường dẫn là đường dẫn tương đối của nội dung.
@Inject
@Path("images/edit.png")
private Asset icon;
Các Path parameter cũng có thể chứa các biểu tượng Tấm thảm được xác định trong AppModule.java phần.
Ví dụ, chúng ta có thể xác định một biểu tượng, skin.root với ngữ cảnh giá trị: skin / basic và sử dụng nó như hình dưới đây -
@Inject
@Path("${skin.root}/style.css")
private Asset style;
Bản địa hóa
Bao gồm các nguồn thông qua tấm thảm cung cấp thêm chức năng. Một trong những chức năng như vậy là "Bản địa hóa". Tấm thảm sẽ kiểm tra ngôn ngữ hiện tại và bao gồm các tài nguyên thích hợp.
Ví dụ: nếu ngôn ngữ hiện tại được đặt là de, sau đó edit_de.png sẽ được bao gồm thay vì edit.png.
CSS
Tấm thảm có hỗ trợ bảng kiểu tích hợp. Tấm thảm sẽ tiêmtapestry.cssnhư một phần của ngăn xếp Javascript cốt lõi. Từ Tapestry 5.4, tấm thảm bao gồmbootstrap css frameworkcũng. Chúng tôi có thể bao gồm bảng kiểu của riêng mình bằng cách sử dụng thẻ liên kết bình thường. Trong trường hợp này, các biểu định kiểu phải nằm trong thư mục gốc của web -/src/main/webapp/.
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestry cung cấp các tùy chọn nâng cao để đưa các biểu định kiểu vào mẫu thông qua tùy chọn mở rộng như đã thảo luận trước đó.
<head>
<link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>
Tapestry cũng cung cấp chú thích Nhập để đưa biểu định kiểu trực tiếp vào các lớp Java.
@Import(stylesheet="context:css/site.css")
public class MyCommonLayout {
}
Tapestry cung cấp rất nhiều tùy chọn để quản lý style sheet thông qua AppModule.java. Một số tùy chọn quan trọng là -
Biểu định kiểu mặc định của tấm thảm có thể bị xóa.
@Contribute(MarkupRenderer.class)
public static void
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) {
configuration.override("InjectDefaultStyleheet", null);
}
Bootstrap cũng có thể bị vô hiệu hóa bằng cách ghi đè đường dẫn của nó.
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
Cho phép thu nhỏ nội dung động (CSS và JavaScript). Chúng tôi cần bao gồmtapestry-webresources phụ thuộc (trong 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 phía máy khách
Thế hệ ứng dụng web hiện tại phụ thuộc rất nhiều vào JavaScript để cung cấp trải nghiệm phía máy khách phong phú. Tapestry thừa nhận điều đó và cung cấp hỗ trợ hạng nhất cho JavaScript. Hỗ trợ JavaScript đã ăn sâu vào tấm thảm và có sẵn ở mọi giai đoạn của chương trình.
Trước đó, Tapestry từng chỉ hỗ trợ Prototype và Scriptaculous. Tuy nhiên, từ phiên bản 5.4, tapestry đã viết lại hoàn toàn lớp JavaScript để làm cho nó càng chung chung càng tốt và cung cấp hỗ trợ lớp đầu tiên cho JQuery, thư viện de-facto cho JavaScript. Ngoài ra, tấm thảm khuyến khích lập trình JavaScript dựa trên mô-đun và hỗ trợ RequestJS, một triển khai phía máy khách phổ biến của AMD (Định nghĩa mô-đun không đồng bộ - đặc tả JavaScript để hỗ trợ mô-đun và phụ thuộc của nó theo cách không đồng bộ).
Vị trí
Các tệp JavaScript là tài sản của Ứng dụng Tapestry. Theo quy tắc nội dung, các tệp JavaScript được đặt trong ngữ cảnh web,/sr/main/webapp/ hoặc đặt bên trong lọ dưới META-INF/assets/ location.
Liên kết các tệp JavaScript
Cách đơn giản nhất để liên kết các tệp JavaScript trong Mẫu XML là sử dụng trực tiếp thẻ script, là: <script language = "javascript" src = "relative/path/to/js"></script>. Tuy nhiên, thảm trang trí không khuyến khích các cách tiếp cận này. Tapestry cung cấp một số tùy chọn để liên kết các tệp JavaScript ngay trong chính Trang / Thành phần. Một số trong số này được đưa ra dưới đây.
@import annotation- Chú thích @import cung cấp tùy chọn liên kết nhiều thư viện JavaScript bằng cách sử dụng biểu thức ngữ cảnh. Nó có thể được áp dụng cho cả lớp Page và phương thức của nó. Nếu được áp dụng cho một lớp Trang, nó sẽ áp dụng cho tất cả các phương thức của nó. Nếu được áp dụng cho Phương thức của Trang, nó chỉ áp dụng cho phương pháp đó và sau đó Tapestry chỉ liên kết thư viện JavaScript khi phương thức được gọi.
@Import(library = {"context:js/jquery.js","context:js/myeffects.js"})
public class MyComponent {
// ...
}
JavaScriptSupport interface - JavaScriptSupport là một giao diện được xác định bởi tấm thảm và nó có một phương thức, importJavaScriptLibraryđể nhập các tệp JavaScript. Đối tượng JavScriptSupport có thể được tạo dễ dàng bằng cách khai báo và chú thích đơn giản với chú thích @Enosystemal.
@Inject @Path("context:/js/myeffects.js")
private Asset myEffects;
@Environmental
private JavaScriptSupport javaScriptSupport;
void setupRender() {
javaScriptSupport.importJavaScriptLibrary(myEffects);
}
JavaScripSupport chỉ có thể được đưa vào một thành phần bằng cách sử dụng @Environmentalchú thích. Đối với các dịch vụ, chúng tôi cần sử dụng@Inject chú thích hoặc thêm nó làm đối số trong phương thức phương thức khởi tạo dịch vụ.
@Inject
private JavaScriptSupport javaScriptSupport;
public MyServiceImpl(JavaScriptSupport support) {
// ...
}
addScript method - Giao diện này tương tự như giao diện JavaScriptSupport ngoại trừ việc nó sử dụng addScript và mã được thêm trực tiếp vào đầu ra ở cuối trang.
void afterRender() {
javaScriptSupport.addScript(
"$('%s').observe('click', hideMe());", container.getClientId());
}
Ngăn xếp JavaScript
Tapestry cho phép một nhóm tệp JavaScript và các biểu định kiểu liên quan được kết hợp và sử dụng như một thực thể duy nhất. Hiện tại, Tapestry bao gồm các ngăn xếp dựa trên Nguyên mẫu và dựa trên JQuery.
Một nhà phát triển có thể phát triển các ngăn xếp của riêng họ bằng cách triển khai JavaScriptStack giao diện và đăng ký nó trong AppModule.java. Sau khi đăng ký, ngăn xếp có thể được nhập bằng cách sử dụng@import chú thích.
@Contribute(JavaScriptStackSource.class)
public static void addMyStack(
MappedConfiguration<String, JavaScriptStack> configuration) {
configuration.addInstance("MyStack", myStack.class);
}
@Import(stack = "MyStack")
public class myPage {
}
Như đã thảo luận trước đó, Thành phần và Trang giống nhau ngoại trừ Trang là thành phần gốc và bao gồm một hoặc nhiều thành phần con. Các thành phần luôn nằm bên trong trang và thực hiện hầu hết các chức năng động của trang.
Các thành phần của tấm thảm hiển thị một liên kết HTML đơn giản đến chức năng lưới phức tạp với interactive AJAX. Một Thành phần cũng có thể bao gồm một thành phần khác. Các thành phần của tấm thảm bao gồm các mục sau:
Component Class - Lớp Java chính của thành phần.
XML Template- Mẫu XML tương tự như mẫu Trang. Lớp thành phần hiển thị mẫu như là đầu ra cuối cùng. Một số thành phần có thể không có mẫu. Trong trường hợp này, đầu ra sẽ được tạo bởi chính lớp thành phần bằng cách sử dụngMarkupWriter lớp học.
Body- Thành phần được chỉ định bên trong mẫu trang có thể có đánh dấu tùy chỉnh và nó được gọi là “Nội dung thành phần”. Nếu mẫu thành phần có<body />thì phần tử <body /> sẽ được thay thế bằng phần thân của thành phần. Điều này tương tự như bố cục đã thảo luận trước đó trong phần mẫu XML.
Rendering - Kết xuất là một quá trình biến đổi khuôn mẫu và nội dung XML của thành phần thành đầu ra thực tế của thành phần.
Parameters - Được sử dụng để tạo giao tiếp giữa các thành phần và các trang và do đó truyền dữ liệu giữa chúng.
Events- Ủy quyền chức năng từ các thành phần cho vùng chứa / cha của nó (các trang hoặc một thành phần khác). Nó được sử dụng rộng rãi trong mục đích điều hướng trang.
Kết xuất
Việc kết xuất một thành phần được thực hiện trong một loạt các giai đoạn được xác định trước. Mỗi pha trong hệ thống thành phần cần có một phương thức tương ứng được xác định theo quy ước hoặc chú thích trong lớp thành phần.
// Using annotaion
@SetupRender
void initializeValues() {
// initialize values
}
// using convention
boolean afterRender() {
// do logic
return true;
}
Các giai đoạn, tên phương thức và chú thích của nó được liệt kê bên dưới.
Chú thích | Tên phương pháp mặc định |
---|---|
@SetupRender | setupRender () |
@BeginRender | beginRender () |
@BeforeRenderTemplate | beforeRenderTemplate () |
@BeforeRenderBody | beforeRenderBody () |
@AfterRenderBody | afterRenderBody () |
@AfterRenderTemplate | afterRenderTemplate () |
@AfterRender | afterRender () |
@CleanupRender | cleanupRender () |
Mỗi giai đoạn có một mục đích cụ thể và chúng như sau:
SetupRender
SetupRender khởi động quá trình kết xuất. Nó thường thiết lập các tham số của thành phần.
BeginRender
BeginRender bắt đầu hiển thị thành phần. Nó thường hiển thị thẻ bắt đầu / bắt đầu của thành phần.
BeforeRenderTemplate
BeforeRenderTemplate được sử dụng để trang trí mẫu XML, thêm đánh dấu đặc biệt xung quanh mẫu. Nó cũng cung cấp một tùy chọn để bỏ qua kết xuất mẫu.
BeforeRenderBody
BeforeRenderTemplate cung cấp một tùy chọn để bỏ qua việc hiển thị phần thân của thành phần.
AfterRenderBody
AfterRenderBody sẽ được gọi sau khi phần thân của thành phần được kết xuất.
AfterRenderTemplate
AfterRenderTemplate sẽ được gọi sau khi mẫu của thành phần được hiển thị.
AfterRender
AfterRender là bản sao của BeginRender và thường hiển thị thẻ đóng.
CleanupRender
CleanupRender là bản sao của SetupRender. Nó giải phóng / định đoạt tất cả các đối tượng được tạo ra trong quá trình kết xuất.
Luồng của các giai đoạn kết xuất không chỉ chuyển tiếp. Nó đi qua lại giữa các pha tùy thuộc vào giá trị trả về của một pha.
Ví dụ: nếu phương thức SetupRender trả về false, thì việc kết xuất sẽ chuyển sang giai đoạn CleanupRender và ngược lại. Để hiểu rõ ràng về dòng chảy giữa các pha khác nhau, hãy kiểm tra dòng chảy trong sơ đồ dưới đây.
Thành phần đơn giản
Hãy để chúng tôi tạo một thành phần đơn giản, Xin chào sẽ có thông báo đầu ra là “Xin chào, Tấm thảm”. Sau đây là mã của thành phần Hello và mẫu của nó.
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>
Thành phần Hello có thể được gọi trong một mẫu trang như sau:
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:hello />
</html>
Tương tự, thành phần có thể hiển thị cùng một đầu ra bằng cách sử dụng MarkupWriter thay vì mẫu như được hiển thị bên dưới.
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>");
}
}
Hãy để chúng tôi thay đổi mẫu thành phần và bao gồm phần tử <body /> như được hiển thị trong khối mã bên dưới.
<html>
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div>
<t:body />
</div>
</html>
Bây giờ, mẫu trang có thể bao gồm phần thân trong phần đánh dấu thành phần như được hiển thị bên dưới.
<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>
Đầu ra sẽ như sau:
<html>
<div>
<p>Hello, Tapestry (from page).</p>
</div>
</html>
Thông số
Mục đích chính của các tham số này là tạo kết nối giữa trường của thành phần và thuộc tính / tài nguyên của trang. Sử dụng các tham số, thành phần và trang tương ứng của nó giao tiếp và truyền dữ liệu giữa nhau. Đây được gọi làTwo Way Data Binding.
Ví dụ, một thành phần hộp văn bản được sử dụng để biểu thị độ tuổi trong trang quản lý người dùng nhận giá trị ban đầu của nó (có sẵn trong cơ sở dữ liệu) thông qua tham số. Một lần nữa, sau khi độ tuổi của người dùng được cập nhật và gửi lại, thành phần sẽ gửi lại độ tuổi đã cập nhật thông qua cùng một tham số.
Để tạo một tham số mới trong lớp thành phần, hãy khai báo một trường và chỉ định @Parameterchú thích. @Parameter này có hai đối số tùy chọn, là:
required- làm cho tham số là bắt buộc. Tấm thảm làm tăng ngoại lệ nếu nó không được cung cấp.
value - chỉ định giá trị mặc định của tham số.
Tham số phải được chỉ định trong mẫu trang dưới dạng thuộc tính của thẻ thành phần. Giá trị của các thuộc tính phải được chỉ định bằng cách sử dụng Binding Expression / Expansion, mà chúng ta đã thảo luận trong các chương trước. Một số mở rộng mà chúng ta đã học trước đó là:
Property expansion (prop:«val») - Lấy dữ liệu từ thuộc tính của lớp trang.
Message expansion (message:«val») - Lấy dữ liệu từ khóa được xác định trong tệp index.properties.
Context expansion (context:«val») - Lấy dữ liệu từ thư mục ngữ cảnh web / src / main / webapp.
Asset expansion (asset:«val») - Lấy dữ liệu từ các tài nguyên được nhúng trong tệp jar, / META-INF / asset.
Symbol expansion (symbol:«val») - Lấy dữ liệu từ các ký hiệu được xác định trong AppModule.javafile.
Tấm thảm có nhiều mở rộng hữu ích hơn, một số trong số đó được đưa ra dưới đây -
Literal expansion (literal:«val») - Một chuỗi chữ.
Var expansion (var:«val») - Cho phép một biến kết xuất của thành phần được đọc hoặc cập nhật.
Validate expansion (validate:«val»)- Một chuỗi chuyên dùng để chỉ định quy tắc xác nhận của một đối tượng. Ví dụ, xác thực: bắt buộc, minLength = 5.
Translate (translate:«val») - Được sử dụng để chỉ định lớp Translator (chuyển đổi biểu diễn phía máy khách sang phía máy chủ) trong xác thực đầu vào.
Block (block:«val») - Id của phần tử khối trong khuôn mẫu.
Component (component:«val») - Id của một thành phần khác trong khuôn mẫu.
Tất cả các mở rộng ở trên đều ở chế độ chỉ đọc ngoại trừ mở rộng Thuộc tính và mở rộng Var. Chúng được thành phần sử dụng để trao đổi dữ liệu với trang. Khi sử dụng mở rộng làm giá trị thuộc tính,${...}không nên sử dụng. Thay vào đó chỉ cần sử dụng phần mở rộng không có ký hiệu đô la và dấu ngoặc nhọn.
Thành phần sử dụng tham số
Hãy để chúng tôi tạo một thành phần mới, HelloWithParameter bằng cách sửa đổi thành phần Hello để hiển thị động thông báo bằng cách thêm name trong lớp thành phần và thay đổi mẫu thành phần và mẫu trang cho phù hợp.
Tạo một lớp thành phần mới HelloWithParameter.java.
Thêm một trường riêng tư và đặt tên nó bằng @Parameterchú thích. Sử dụng đối số bắt buộc để làm cho nó bắt buộc.
@Parameter(required = true)
private String name;
Thêm trường riêng tư, kết quả bằng @Properychú thích. Thuộc tính kết quả sẽ được sử dụng trong mẫu thành phần. Mẫu thành phần không có quyền truy cập vào các trường được chú thích bằng@Parameter và chỉ có thể truy cập vào các trường được chú thích bằng @Property. Biến có sẵn trong các mẫu thành phần được gọi là Biến kết xuất.
@Property
private String result;
Thêm một phương thức RenderBody và sao chép giá trị từ tham số tên sang thuộc tính kết quả.
@BeginRender
void initializeValues() {
result = name;
}
Thêm một mẫu thành phần mới HelloWithParamter.tml và sử dụng thuộc tính kết quả để hiển thị thông báo.
<div> Hello, ${result} </div>
Thêm thuộc tính mới, Tên người dùng trong trang thử nghiệm (testhello.java).
public String getUsername() {
return "User1";
}
Sử dụng thành phần mới được tạo trong mẫu trang và đặt thuộc tính Tên người dùng trong tham số tên của HelloWithParameter thành phần.
<t:helloWithParameter name = "username" />
Danh sách đầy đủ như sau:
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>
Kết quả sẽ như sau:
<div> Hello, User1 </div>
Thông số nâng cao
Trong các chương trước, chúng ta đã phân tích cách tạo và sử dụng một tham số đơn giản trong một thành phần tùy chỉnh. Thông số nâng cao cũng có thể chứa đánh dấu hoàn chỉnh. Trong trường hợp này, đánh dấu phải được chỉ định bên trong thẻ thành phần, chẳng hạn như phần phụ trong mẫu trang. Thành phần if tích hợp có đánh dấu cho cả điều kiện thành công và thất bại. Đánh dấu thành công được chỉ định làm phần thân của thẻ thành phần và đánh dấu thất bại được chỉ định bằng cách sử dụngelseparameter.
Hãy để chúng tôi xem cách sử dụng ifthành phần. Thành phần if có hai tham số -
test - Tham số dựa trên thuộc tính đơn giản.
Else - Tham số nâng cao được sử dụng để chỉ định đánh dấu thay thế, nếu điều kiện không thành công
Tapestry sẽ kiểm tra giá trị của thuộc tính thử nghiệm bằng cách sử dụng logic sau đây và trả về true hoặc false. Đây được gọi làType Coercion, một cách chuyển đổi một đối tượng thuộc kiểu này sang kiểu khác có cùng nội dung.
Nếu kiểu dữ liệu là String, “Đúng” nếu không trống và không phải là chuỗi chữ “Sai” (không phân biệt chữ hoa chữ thường).
Nếu kiểu dữ liệu là Number, Đúng nếu khác 0.
Nếu kiểu dữ liệu là Collection, Đúng nếu không trống.
Nếu kiểu dữ liệu là Object, Đúng (miễn là nó không rỗng).
Nếu điều kiện vượt qua, thành phần sẽ hiển thị phần thân của nó; nếu không, nó sẽ hiển thị phần thân của tham số else.
Danh sách đầy đủ như sau:
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>
Sự kiện thành phần / Điều hướng trang
Ứng dụng tấm thảm là một collection of Pagestương tác với nhau. Cho đến bây giờ, chúng ta đã học cách tạo các trang riêng lẻ mà không cần bất kỳ thông tin liên lạc nào giữa chúng. Mục đích chính của sự kiện Thành phần là cung cấp sự tương tác giữa các trang (cả trong các trang) bằng cách sử dụng các sự kiện phía máy chủ. Hầu hết các sự kiện thành phần bắt nguồn từ các sự kiện phía máy khách.
Ví dụ: khi người dùng nhấp vào liên kết trong một trang, Tapestry sẽ gọi chính trang đó với thông tin mục tiêu thay vì gọi trang mục tiêu và tăng sự kiện phía máy chủ. Trang tấm thảm sẽ nắm bắt sự kiện, xử lý thông tin mục tiêu và thực hiện chuyển hướng phía máy chủ đến trang mục tiêu.
Tấm thảm sau một Post/Redirect/Get (RPG) design patternđể điều hướng trang. Trong RPG, khi người dùng thực hiện yêu cầu đăng bài bằng cách gửi biểu mẫu, máy chủ sẽ xử lý dữ liệu đã đăng, nhưng không trả lại phản hồi trực tiếp. Thay vào đó, nó sẽ thực hiện chuyển hướng phía máy khách đến một trang khác, điều này sẽ xuất ra kết quả. Mẫu RPG được sử dụng để ngăn việc gửi biểu mẫu trùng lặp thông qua nút quay lại trình duyệt, nút làm mới trình duyệt, v.v., Tapestry cung cấp mẫu RPG bằng cách cung cấp hai loại yêu cầu sau.
Component Event Request- Loại yêu cầu này nhắm mục tiêu đến một thành phần cụ thể trong một trang và nêu ra các sự kiện trong thành phần. Yêu cầu này chỉ thực hiện chuyển hướng và không xuất ra phản hồi.
Render Request - Các loại yêu cầu này nhắm mục tiêu đến một trang và truyền phản hồi trở lại máy khách.
Để hiểu các sự kiện thành phần và điều hướng trang, chúng ta cần biết mẫu URL của yêu cầu tấm thảm. Mẫu URL cho cả hai loại yêu cầu như sau:
Component Event Requests -
/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
Render Request -
/<<page_name_with_path>>/<<context_information>>
Một số ví dụ về các mẫu URL là:
Trang chỉ mục có thể được yêu cầu bởi https://«domain»/«app»/index.
Nếu trang Chỉ mục có sẵn dưới quản trị viên thư mục con, thì nó có thể được yêu cầu bởi https://«domain»/«app»/admin/index.
Nếu người dùng nhấp vào ActionLink component với id test trong trang chỉ mục, thì URL sẽ là https://«domain»/«app»/index.test.
Sự kiện
Theo mặc định, Tapestry tăng OnPassivate và OnActivatesự kiện cho tất cả các yêu cầu. Đối với loại yêu cầu sự kiện Thành phần, thảm trang trí thêm một hoặc nhiều sự kiện tùy thuộc vào thành phần. Thành phần ActionLink tăng sự kiện Hành động, trong khi thành phần Biểu mẫu tăng nhiều sự kiện, chẳng hạn nhưValidate, Success, Vân vân.,
Các sự kiện có thể được xử lý trong lớp trang bằng cách sử dụng trình xử lý phương thức tương ứng. Trình xử lý phương thức được tạo thông qua quy ước đặt tên phương thức hoặc thông qua@OnEventchú thích. Định dạng của quy ước đặt tên phương thức làOn«EventName»From«ComponentId».
Một sự kiện hành động của thành phần ActionLink với id test có thể được xử lý bằng một trong các phương pháp sau:
void OnActionFromTest() {
}
@OnEvent(component = "test", name = "action")
void CustomFunctionName() {
}
Nếu tên phương thức không có bất kỳ thành phần cụ thể nào, thì phương thức sẽ được gọi cho tất cả các thành phần có sự kiện phù hợp.
void OnAction() {
}
Sự kiện OnPassivate và OnActivate
OnPassivate được sử dụng để cung cấp thông tin ngữ cảnh cho trình xử lý sự kiện OnActivate. Nói chung, Tapestry cung cấp thông tin ngữ cảnh và nó có thể được sử dụng làm đối số trong trình xử lý OnActivateevent.
Ví dụ: nếu thông tin ngữ cảnh là 3 kiểu int, thì sự kiện OnActivate có thể được gọi là -
void OnActivate(int id) {
}
Trong một số trường hợp, thông tin ngữ cảnh có thể không có sẵn. Trong tình huống này, chúng tôi có thể cung cấp thông tin ngữ cảnh cho trình xử lý sự kiện OnActivate thông qua trình xử lý sự kiện OnPassivate. Kiểu trả về của trình xử lý sự kiện OnPassivate nên được sử dụng làm đối số của trình xử lý sự kiện OnActivate.
int OnPassivate() {
int id = 3;
return id;
}
void OnActivate(int id) {
}
Giá trị trả lại của trình xử lý sự kiện
Tapestry vấn đề chuyển hướng trang dựa trên các giá trị trả về của trình xử lý sự kiện. Trình xử lý sự kiện sẽ trả về bất kỳ giá trị nào sau đây.
Null Response- Trả về giá trị null. Tapestry sẽ tạo URL của trang hiện tại và gửi cho khách hàng dưới dạng chuyển hướng.
public Object onAction() {
return null;
}
String Response- Trả về giá trị chuỗi. Tapestry sẽ tạo URL của trang phù hợp với giá trị và gửi đến khách hàng dưới dạng chuyển hướng.
public String onAction() {
return "Index";
}
Class Response- Trả về một lớp trang. Tapestry sẽ xây dựng URL của lớp trang được trả về và gửi đến máy khách dưới dạng chuyển hướng.
public Object onAction() {
return Index.class
}
Page Response- Trả về một trường được chú thích bằng @InjectPage. Tapestry sẽ tạo URL của trang được đưa vào và gửi đến máy khách dưới dạng chuyển hướng.
@InjectPage
private Index index;
public Object onAction(){
return index;
}
HttpError- Trả về đối tượng HTTPError. Tấm thảm sẽ gây ra lỗi HTTP phía máy khách.
public Object onAction(){
return new HttpError(302, "The Error message);
}
Link Response- Trả về một thể hiện liên kết trực tiếp. Tapestry sẽ tạo URL từ đối tượng Liên kết và gửi đến máy khách dưới dạng chuyển hướng.
Stream Response - Trả về StreamResponsevật. Tapestry sẽ gửi luồng dưới dạng phản hồi trực tiếp đến trình duyệt của khách hàng. Nó được sử dụng để tạo báo cáo và hình ảnh trực tiếp và gửi cho khách hàng.
Url Response - Trả về java.net.URLvật. Tapestry sẽ lấy URL tương ứng từ đối tượng và gửi đến máy khách dưới dạng chuyển hướng.
Object Response- Trả về bất kỳ giá trị nào khác với các giá trị đã chỉ định ở trên. Tấm thảm sẽ gây ra lỗi.
Bối cảnh sự kiện
Nói chung, trình xử lý sự kiện có thể lấy thông tin ngữ cảnh bằng cách sử dụng các đối số. Ví dụ: nếu thông tin ngữ cảnh là 3 kiểu int, thì trình xử lý sự kiện sẽ là:
Object onActionFromTest(int id) {
}
Tapestry xử lý đúng thông tin ngữ cảnh và cung cấp thông tin đó cho các phương thức thông qua các đối số. Đôi khi, Tapestry có thể không xử lý được đúng cách do quá trình lập trình phức tạp. Khi đó, chúng tôi có thể nhận được thông tin ngữ cảnh đầy đủ và tự xử lý.
Object onActionFromEdit(EventContext context) {
if (context.getCount() > 0) {
this.selectedId = context.get(0);
} else {
alertManager.warn("Please select a document.");
return null;
}
}
Chương này giải thích về các thành phần tích hợp mà Tapestry có với các ví dụ phù hợp. Tấm thảm hỗ trợ hơn 65 thành phần tích hợp. Bạn cũng có thể tạo các thành phần tùy chỉnh. Hãy để chúng tôi trình bày chi tiết một số thành phần đáng chú ý.
Nếu thành phần
Thành phần if được sử dụng để hiển thị một khối có điều kiện. Điều kiện được kiểm tra bằng một tham số thử nghiệm.
Tạo một trang IfSample.java như hình dưới đây -
package com.example.MyFirstApplication.pages;
public class Ifsample {
public String getUser() {
return "user1";
}
}
Bây giờ, hãy tạo một tệp mẫu tương ứng như sau:
<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>
Yêu cầu trang sẽ đưa ra kết quả như hình bên dưới.
Result - http: // localhost: 8080 / MyFirstApplication / ifsample
Thành phần trừ khi và ủy quyền
Các unless componentđối lập với thành phần if đã được thảo luận ở trên. Trong khidelegate componentkhông tự mình thực hiện bất kỳ kết xuất nào. Thay vào đó, nó thường ủy quyền đánh dấu cho phần tử khối. Trừ khi và nếu các thành phần có thể sử dụng ủy quyền và khối để hoán đổi nội dung động có điều kiện.
Tạo một trang Unless.java như sau.
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;
}
}
}
Bây giờ, hãy tạo một tệp mẫu tương ứng như sau:
<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>
Yêu cầu trang sẽ đưa ra kết quả như hình bên dưới.
Result - http: // localhost: 8080 / MyFirstApplication / trừ khi
Thành phần vòng lặp
Thành phần vòng lặp là thành phần cơ bản để lặp qua các mục tập hợp và hiển thị phần thân cho mọi giá trị / lần lặp.
Tạo một trang Loop như hình dưới đây -
Loop.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class Loop {
@Property
private int i;
}
Sau đó, tạo mẫu tương ứng 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>
Thành phần vòng lặp có hai tham số sau:
source- Nguồn sưu tầm. 1… 5 là một phần mở rộng thuộc tính được sử dụng để tạo một mảng với một phạm vi xác định.
var- Kết xuất biến. Được sử dụng để hiển thị giá trị hiện tại trong phần nội dung của mẫu.
Yêu cầu trang sẽ hiển thị kết quả như hình dưới đây -
Thành phần liên kết trang
Thành phần Liên kết trang được sử dụng để liên kết một trang từ trang này sang trang khác. Tạo trang kiểm tra Liên kết trang như bên dưới -PageLink.java.
package com.example.MyFirstApplication.pages;
public class PageLink {
}
Sau đó, tạo một tệp mẫu tương ứng như hình dưới đây -
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>
Thành phần Liên kết trang có một tham số trang sẽ tham chiếu đến trang tấm thảm mục tiêu.
Result - http: // localhost: 8080 / myFirstApplication / pagelink
Thành phần EventLink
Thành phần EventLink gửi tên sự kiện và tham số tương ứng qua URL. Tạo một lớp trang EventsLink như hình bên dưới.
Sự kiệnLink.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;
}
}
Sau đó, tạo tệp mẫu “Liên kết sự kiện” tương ứng như sau:
Sự kiệnLink.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 có hai tham số sau:
Event- Tên của sự kiện sẽ được kích hoạt trong thành phần EventLink. Theo mặc định, nó trỏ đến id của thành phần.
Context- Nó là một tham số tùy chọn. Nó xác định bối cảnh cho liên kết.
Result - http: // localhost: 8080 / myFirstApplication / EventsLink
Sau khi nhấp vào giá trị đếm, trang sẽ hiển thị tên sự kiện trong URL như được hiển thị trong ảnh chụp màn hình đầu ra sau đây.
Thành phần ActionLink
Thành phần ActionLink tương tự như thành phần EventLink, nhưng nó chỉ gửi id thành phần đích. Tên sự kiện mặc định là hành động.
Tạo một trang “ActivationLinks.java” như hình dưới đây,
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;
}
}
Bây giờ, tạo một tệp mẫu tương ứng như hình dưới đây -
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>
Đây, OnActionFromSub phương thức sẽ được gọi khi nhấp vào thành phần ActionLink.
Result - http: // localhost: 8080 / myFirstApplication / ActivationsLink
Thành phần cảnh báo
Hộp thoại cảnh báo chủ yếu được sử dụng để đưa ra thông báo cảnh báo cho người dùng. Ví dụ: nếu trường nhập yêu cầu một số văn bản bắt buộc nhưng người dùng không cung cấp bất kỳ đầu vào nào, thì như là một phần của xác thực, bạn có thể sử dụng hộp cảnh báo để đưa ra thông báo cảnh báo.
Tạo một trang “Cảnh báo” như được hiển thị trong chương trình sau.
Alerts.java
package com.example.MyFirstApplication.pages;
public class Alerts {
public String getUser() {
return "user1";
}
}
Sau đó, tạo một tệp mẫu tương ứng như sau:
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>
Cảnh báo có ba mức độ nghiêm trọng, đó là -
- Info
- Warn
- Error
Mẫu trên được tạo bằng cách sử dụng cảnh báo thông tin. Nó được định nghĩa làalert-info. Bạn có thể tạo các mức độ nghiêm trọng khác tùy theo nhu cầu.
Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/Alerts
Các Form Componentđược sử dụng để tạo biểu mẫu trong trang thảm để người dùng nhập. Biểu mẫu có thể chứa các trường văn bản, trường ngày tháng, trường hộp kiểm, chọn các tùy chọn, nút gửi và hơn thế nữa.
Chương này giải thích chi tiết về một số thành phần biểu mẫu đáng chú ý.
Thành phần hộp kiểm
Thành phần hộp kiểm được sử dụng để lựa chọn giữa hai tùy chọn loại trừ lẫn nhau. Tạo trang bằng Hộp kiểm như hình dưới đây -
Checkbox.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class Checkbox {
@Property
private boolean check1;
@Property
private boolean check2;
}
Bây giờ, hãy tạo một mẫu tương ứng Checkbox.tml như hình dưới đây -
<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>
Tại đây, id tham số hộp kiểm khớp với giá trị Boolean tương ứng.
Result - Sau khi yêu cầu trang, hộp kiểm http: // localhost: 8080 / myFirstApplication / nó cho kết quả như sau.
Thành phần trường văn bản
Thành phần TextField cho phép người dùng chỉnh sửa một dòng văn bản. Tạo một trangText như hình bên dưới.
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;
}
Sau đó, tạo một mẫu tương ứng như hình bên dưới - 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>
Ở đây, trang Văn bản bao gồm một thuộc tính có tên fname và lname. Các id thành phần được truy cập bởi các thuộc tính.
Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/Text
Thành phần PasswordField
PasswordField là một mục nhập trường văn bản chuyên biệt cho mật khẩu. Tạo mật khẩu trang như hình dưới đây -
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;
}
Bây giờ, tạo một tệp mẫu tương ứng như hình dưới đây -
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>
Ở đây, thành phần PasswordField có id tham số, nó trỏ đến thuộc tính pwd. Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/Password
Thành phần TextArea
Thành phần TextArea là một điều khiển văn bản đầu vào nhiều dòng. Tạo một trang TxtArea như hình bên dưới.
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;
}
Sau đó, tạo một tệp mẫu tương ứng như hình dưới đây.
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>
Ở đây, id tham số thành phần TextArea trỏ đến thuộc tính “str”. Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/TxtArea**
Chọn thành phần
Thành phần Chọn chứa một danh sách các lựa chọn thả xuống. Tạo một trang SelectOption như hình bên dưới.
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
}
}
Sau đó, tạo một mẫu tương ứng như sau:
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>
Ở đây, thành phần Chọn có hai tham số:
Type - Loại thuộc tính là enum.
Id - Id trỏ đến thuộc tính Tapestry “color1”.
Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/SelectOption
Thành phần RadioGroup
Thành phần RadioGroup cung cấp một nhóm vùng chứa cho các thành phần Radio. Các thành phần Radio và RadioGroup làm việc cùng nhau để cập nhật thuộc tính của một đối tượng. Thành phần này nên quấn quanh các thành phần Radio khác. Tạo một trang mới “Radiobutton.java” như hình dưới đây -
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;
}
Sau đó, tạo một tệp mẫu tương ứng như hình dưới đây -
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>
Ở đây, id thành phần RadioGroup được ràng buộc với thuộc tính “value”. Yêu cầu trang sẽ cho ra kết quả như sau.
http://localhost:8080/myFirstApplication/Radiobutton
Gửi thành phần
Khi người dùng nhấp vào nút gửi, biểu mẫu sẽ được gửi đến địa chỉ được chỉ định trong cài đặt hành động của thẻ. Tạo một trangSubmitComponent như hình bên dưới.
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.InjectPage;
public class SubmitComponent {
@InjectPage
private Index page1;
Object onSuccess() {
return page1;
}
}
Bây giờ, tạo một tệp mẫu tương ứng như hình dưới đây.
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>
Tại đây, thành phần Gửi sẽ gửi giá trị đến trang Chỉ mục. Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/SubmitComponent
Xác thực biểu mẫu
Xác thực biểu mẫu thường xảy ra tại máy chủ sau khi máy khách đã nhập tất cả dữ liệu cần thiết và sau đó gửi biểu mẫu. Nếu dữ liệu được nhập bởi máy khách không chính xác hoặc bị thiếu đơn giản, máy chủ sẽ phải gửi lại tất cả dữ liệu cho máy khách và yêu cầu gửi lại biểu mẫu với thông tin chính xác.
Chúng ta hãy xem xét ví dụ đơn giản sau để hiểu quá trình xác nhận.
Tạo một trang Validate như hình bên dưới.
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;
}
Bây giờ, tạo một tệp mẫu tương ứng như hình dưới đây.
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>
Xác thực biểu mẫu có các tham số quan trọng sau:
Max - xác định giá trị lớn nhất, ví dụ = «giá trị lớn nhất, 20».
MaxDate- xác định maxDate, ví dụ = «ngày tối đa, 06/09/2013». Tương tự, bạn cũng có thể gán MinDate.
MaxLength - maxLength for eg = «chiều dài tối đa, 80».
Min - tối thiểu.
MinLength - Độ dài tối thiểu cho vd = «độ dài minmum, 2».
Email - Xác thực email sử dụng email tiêu chuẩn regexp ^ \ w [._ \ w] * \ w @ \ w [-._ \ w] * \ w \. \ W2,6 $ hoặc không.
Yêu cầu trang sẽ tạo ra kết quả sau:
http://localhost:8080/myFirstApplication/Validate
AJAX là viết tắt của Asynchronous JavaScript and XML. Đây là một kỹ thuật để tạo các ứng dụng web tốt hơn, nhanh hơn và tương tác hơn với sự trợ giúp củaXML, JSON, HTML, CSS, và JavaScript. AJAX cho phép bạn gửi và nhận dữ liệu không đồng bộ mà không cần tải lại trang web nên rất nhanh.
Thành phần vùng
Thành phần Vùng được sử dụng để cung cấp nội dung (đánh dấu) cũng như vị trí của chính nội dung đó. Phần thân của Zone Component được Tapestry sử dụng nội bộ để tạo nội dung. Khi nội dung động được tạo, Tapestry sẽ gửi nội dung đó đến máy khách, hiển thị dữ liệu ở đúng vị trí, kích hoạt và tạo hoạt ảnh cho HTML để thu hút sự chú ý của người dùng.
Thành phần Zone này được sử dụng cùng với một thành phần EventLink. EventLink có tùy chọn để liên kết nó với một vùng cụ thể bằng cách sử dụngt:zonethuộc tính. Sau khi vùng được định cấu hình trong EventLink, việc nhấp vào EventLink sẽ kích hoạt cập nhật vùng. Ngoài ra, các sự kiện EventLink (refreshZone) có thể được sử dụng để kiểm soát việc tạo dữ liệu động.
Một ví dụ đơn giản về AJAX như sau:
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();
}
}
Kết quả sẽ hiển thị tại: http: // localhost: 8080 / MyFirstApplication / AjaxZone
Trong chương này, chúng ta sẽ thảo luận về việc tích hợp BeanEditForm và Grid componentvới Hibernate. Hibernate được tích hợp vào tấm thảm thông qua mô-đun ngủ đông. Để bật mô-đun ngủ đông, hãy thêm phụ thuộc thảm trang trí-ngủ đông và tùy chọnhsqldb bên trong pom.xmltập tin. Bây giờ, hãy định cấu hình ngủ đông thông quahibernate.cfg.xml tệp được đặt ở gốc của thư mục tài nguyên.
pom.xml (một phần)
<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>
Hãy để chúng tôi xem cách tạo employee add page bằng cách sử dụng thành phần BeanEditForm và employee list pagebằng cách sử dụng thành phần Grid. Lớp bền vững được xử lý bởi mô-đun Hibernate.
Tạo một lớp nhân viên và trang trí bằng chú thích @Entity. Sau đó, thêm chú thích xác thực cho các trường có liên quan và ngủ đông chú thích liên quan @Id và @GeneratedValue cho trường id. Ngoài ra, hãy tạo giới tính dưới dạng kiểu enum.
Employee.java
package com.example.MyFirstApplication.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.apache.tapestry5.beaneditor.NonVisual;
import org.apache.tapestry5.beaneditor.Validate;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NonVisual
public Long id;
@Validate("required")
public String firstName;
@Validate("required")
public String lastName;
@Validate("required")
public String userName;
@Validate("required")
public String password;
@Validate("required")
public String email;
public String phone;
@Validate("required")
public String Street;
@Validate("required")
public String city;
@Validate("required")
public String state;
@Validate("required,regexp=^\\d{5}(-\\d{4})?$")
public String zip;
}
Gender.java (enum)
package com.example.MyFirstApplication.data;
public enum Gender {
Male, Female
}
Tạo trang danh sách nhân viên, ListEmployee.java trong thư mục mới nhân viên dưới các trang và tệp mẫu tương ứng ListEaffee.tml tại /src/main/resources/pages/employeethư mục. Tapestry cung cấp một URL ngắn cho các thư mục con bằng cách xóa dữ liệu lặp lại.
Ví dụ: có thể truy cập trang ListEaffee bằng một URL bình thường - (/ worker / listening Employee) và bằng URL ngắn - (/ worker / list).
Đưa phiên Hibernate vào trang danh sách bằng cách sử dụng chú thích @Inject. Xác định một thuộc tínhgetEmployeestrong trang danh sách và điền nó với các nhân viên sử dụng đối tượng phiên được tiêm. Hoàn thành mã cho hạng nhân viên như hình dưới đây.
ListEaffee.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();
}
}
Tạo tệp mẫu cho lớp ListEaffee. Mẫu sẽ có hai thành phần chính, đó là -
PageLink - Tạo trang liên kết nhân viên.
Grid- Được sử dụng để hiển thị chi tiết nhân viên. Thành phần lưới có các thuộc tính nguồn để đưa vào danh sách nhân viên và bao gồm các thuộc tính để bao gồm các trường sẽ được hiển thị.
ListEaffee.tml (liệt kê tất cả nhân viên)
<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>
Tạo tệp mẫu tạo nhân viên và bao gồm thành phần BeanEditForm. Thành phần có các thuộc tính sau:
object - Bao gồm nguồn.
reorder - Xác định thứ tự của các trường sẽ được hiển thị.
submitlabel - Thông báo của nút gửi biểu mẫu
Mã hóa hoàn chỉnh như sau:
<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>
Tạo lớp tạo nhân viên và bao gồm phiên, thuộc tính nhân viên, trang danh sách (liên kết điều hướng) và xác định sự kiện OnSuccess (nơi cập nhật dữ liệu) của thành phần. Dữ liệu phiên được lưu vào cơ sở dữ liệu bằng phiên ngủ đông.
Mã hóa hoàn chỉnh như sau:
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;
}
}
Thêm CreateEmployee.propertiesvà bao gồm thông báo sẽ được sử dụng trong xác thực biểu mẫu. Mã hoàn chỉnh như sau:
zip-regexp=^\\d{5}(-\\d{4})?$
zip-regexp-message = Zip Codes are five or nine digits. Example: 02134 or 901251655.
submit-label = Create Employee
Ảnh chụp màn hình của trang tạo nhân viên và trang danh sách được hiển thị bên dưới -
Mỗi ứng dụng web nên có một số cách để lưu trữ dữ liệu người dùng nhất định như đối tượng người dùng, sở thích của người dùng, v.v. Ví dụ: trong ứng dụng giỏ hàng, các mặt hàng / sản phẩm đã chọn của người dùng phải được lưu trong một nhóm tạm thời (giỏ hàng) cho đến khi người dùng thích để mua các sản phẩm. Chúng ta có thể lưu các mặt hàng trong cơ sở dữ liệu, nhưng sẽ quá đắt vì tất cả người dùng sẽ không mua các mặt hàng đã chọn. Vì vậy, chúng tôi cần một sự sắp xếp tạm thời để lưu trữ / tồn tại các mục. Apache Tapestry Cung cấp hai cách để duy trì dữ liệu và chúng -
- Dữ liệu trang ổn định
- Lưu trữ phiên
Cả hai đều có những ưu điểm và hạn chế riêng. Chúng tôi sẽ kiểm tra nó trong các phần sau.
Dữ liệu trang ổn định
Dữ liệu trang ổn định là một khái niệm đơn giản để duy trì dữ liệu trong một trang duy nhất giữa các yêu cầu và nó còn được gọi là Page Level Persistence. Nó có thể được thực hiện bằng cách sử dụng@Persist chú thích.
@Persist
public int age;
Khi một trường được chú thích bằng @Persist, giá trị của trường sẽ được duy trì theo yêu cầu và nếu giá trị được thay đổi trong khi yêu cầu, giá trị đó sẽ được phản ánh khi được truy cập vào lần sau. Apache Tapestry cung cấp năm loại chiến lược để thực hiện khái niệm @Persist. Chúng như sau:
Session Strategy - Dữ liệu được duy trì bằng cách sử dụng Phiên và đó là chiến lược mặc định.
Flash Strategy- Dữ liệu vẫn tồn tại bằng Session, nhưng nó chỉ tồn tại trong thời gian rất ngắn. Dữ liệu sẽ chỉ có sẵn trong một lần yêu cầu tiếp theo.
@Persist(PersistenceConstants.FLASH)
private int age;
Client Strategy - Dữ liệu được lưu giữ ở phía máy khách như chuỗi truy vấn URL, trường ẩn trong biểu mẫu, v.v.
@Persist(PersistenceConstants.FLASH)
private int age;
Hibernate Entity Strategy- Dữ liệu được duy trì bằng cách sử dụng mô-đun Hibernate làm Thực thể. Thực thể sẽ được lưu trữ trong Hibernate và tham chiếu của nó (tên lớp Java và khóa chính của nó) sẽ được lưu dưới dạng mã thông báo trongHttpSession. Thực thể sẽ được khôi phục bằng cách sử dụng mã thông báo có sẵn trong HttpSession.
@Persist(HibernatePersistenceConstants.ENTITY)
private Category category;
JPA Entity Strategy- Dữ liệu được duy trì bằng cách sử dụng mô-đun JPA. Nó sẽ chỉ có thể lưu trữ Thực thể.
@Persist(JpaPersistenceConstants.ENTITY)
private User user;
Lưu trữ phiên
Lưu trữ phiên là một khái niệm nâng cao được sử dụng để lưu trữ dữ liệu cần có sẵn trên các trang như dữ liệu trong trình hướng dẫn nhiều trang, thông tin chi tiết về người dùng đã đăng nhập, v.v. Lưu trữ phiên cung cấp hai tùy chọn, một để lưu trữ đối tượng phức tạp và một để lưu trữ các giá trị đơn giản
Session Store Object - Dùng để lưu trữ các đối tượng phức tạp.
Session Attributes - Dùng để lưu trữ các giá trị đơn giản.
Đối tượng lưu trữ phiên (SSO)
Một SSO có thể được tạo bằng cách sử dụng @SessionStorechú thích. SSO sẽ lưu trữ đối tượng bằng cách sử dụng loại đối tượng. Ví dụ,Cart Objectsẽ được lưu trữ bằng tên lớp Cart làm mã thông báo. Vì vậy, bất kỳ đối tượng phức tạp nào cũng có thể được lưu trữ một lần trong một ứng dụng (một đối tượng cho mỗi người dùng).
public class MySSOPage {
@SessionState
private ShoppingCart cart;
}
SSO là một cửa hàng chuyên dụng và chỉ nên được sử dụng để lưu trữ các đối tượng phức tạp / đặc biệt. Các kiểu dữ liệu đơn giản cũng có thể được lưu trữ bằng SSO, nhưng việc lưu trữ các kiểu dữ liệu đơn giản như Chuỗi làm cho nó chỉ lưu trữ một giá trị “Chuỗi” trong ứng dụng. Chỉ đơn giản là không thể sử dụng một giá trị “Chuỗi” trong ứng dụng. Bạn có thể sử dụng các kiểu dữ liệu đơn giản vì Apache Tapestry cung cấp Thuộc tính phiên.
Thuộc tính phiên
Thuộc tính phiên cho phép dữ liệu được lưu trữ theo tên thay vì loại của nó.
public class MyPage {
@SessionAttribute
private String loggedInUsername;
}
Theo mặc định, Thuộc tính phiên sử dụng tên trường để tham chiếu dữ liệu trong phiên. Chúng ta có thể thay đổi tên tham chiếu bằng tham số chú thích như hình dưới đây -
public class MyPage {
@SessionAttribute("loggedInUserName")
private String userName;
}
Một trong những vấn đề chính khi sử dụng tên làm tham chiếu phiên là chúng ta có thể vô tình sử dụng cùng một tên trong nhiều lớp / trang. Trong trường hợp này, dữ liệu được lưu trữ có thể thay đổi bất ngờ. Để khắc phục sự cố này, sẽ tốt hơn nếu sử dụng tên cùng với tên lớp / trang và tên gói nhưcom.myapp.pages.register.email, trong đó com.myapp.pages là tên gói, register là tên trang / lớp và cuối cùng email là tên biến (sẽ được lưu trữ).
Trong chương này, chúng ta sẽ thảo luận chi tiết về một số tính năng nâng cao của Apache Tapestry.
Đảo ngược kiểm soát
Tapestry cung cấp thư viện Inversion of Control tích hợp sẵn. Tấm thảm được tích hợp sâu vào IoC và sử dụng IoC cho tất cả các tính năng của nó. Cấu hình IoC của Tapestry dựa trên chính Java thay vì XML như nhiều vùng chứa IoC khác. Các mô-đun dựa trên IoC của Tapestry được đóng gói thành tệp JAR và chỉ được đưa vào classpath với cấu hình bằng không. Việc sử dụng IoC của tấm thảm dựa trên độ nhẹ, có nghĩa là -
Các giao diện nhỏ của hai hoặc ba phương thức.
Các phương thức nhỏ với hai hoặc ba tham số.
Giao tiếp ẩn danh thông qua các sự kiện, thay vì lời gọi phương thức rõ ràng.
Mô-đun
Mô-đun là một cách để mở rộng chức năng của ứng dụng Tapestry. Tấm thảm có cả các mô-đun tích hợp và số lượng lớn các mô-đun của bên thứ ba. Hibernate là một trong những mô-đun nóng và rất hữu ích do Tapestry cung cấp. Nó cũng có các mô-đun tích hợp JMX, JPA, Spring Framework, JSR 303 Bean Validation, JSON, v.v. Một số mô-đun của bên thứ ba đáng chú ý là:
- 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
Ngoại lệ thời gian chạy
Một trong những tính năng tốt nhất của tấm thảm là Detailed Error Reporting. Tapestry giúp nhà phát triển bằng cách cung cấp báo cáo ngoại lệ hiện đại. Báo cáo ngoại lệ của tấm thảm là HTML đơn giản với thông tin chi tiết. Bất kỳ ai cũng có thể dễ dàng hiểu được bản báo cáo. Tấm thảm hiển thị lỗi trong HTML cũng như lưu ngoại lệ trong văn bản thuần túy với ngày và giờ xảy ra ngoại lệ. Điều này cũng sẽ giúp nhà phát triển kiểm tra ngoại lệ trong môi trường sản xuất. Nhà phát triển có thể tự tin khắc phục bất kỳ sự cố nào như mẫu bị hỏng, giá trị rỗng không mong muốn, yêu cầu chưa được so khớp, v.v.
Lớp Trực tiếp và Tải lại Mẫu
Tấm thảm sẽ tự động tải lại các mẫu và lớp khi được sửa đổi. Tính năng này cho phép phản ánh ngay lập tức các thay đổi của ứng dụng mà không cần trải qua chu kỳ xây dựng và thử nghiệm. Ngoài ra, tính năng này cải thiện đáng kể năng suất phát triển ứng dụng.
Hãy coi gói gốc của ứng dụng là org.example.myfirstapp. Sau đó, các lớp trong các đường dẫn sau được quét để tải lại.
- org.example.myfirstapp.pages
- org.example.myfirstapp.components
- org.example.myfirstapp.mixins
- org.example.myfirstapp.base
- org.example.myfirstapp.services
Việc tải lại lớp trực tiếp có thể bị vô hiệu hóa bằng cách đặt chế độ sản xuất thành true trong AppModule.java.
configuration.add(SymbolicConstants.PRODUCTION_MODE,”false”);
Kiểm tra đơn vị
Kiểm thử đơn vị là một kỹ thuật mà các trang và thành phần riêng lẻ được kiểm tra. Tapestry cung cấp các tùy chọn dễ dàng cho các trang và thành phần kiểm tra đơn vị.
Kiểm tra đơn vị một trang: Tấm thảm cung cấp một lớp PageTesterđể kiểm tra ứng dụng. Điều này hoạt động như cả trình duyệt và vùng chứa servlet. Nó hiển thị trang mà không cần trình duyệt ở phía máy chủ và tài liệu kết quả có thể được kiểm tra để hiển thị chính xác. Xem xét một trang đơn giảnHello, hiển thị lời chào và văn bản xin chào được đặt bên trong phần tử html có id hello_id. Để kiểm tra tính năng này, chúng ta có thể sử dụng PageTester như hình dưới đây:
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 cũng cung cấp tùy chọn để bao gồm thông tin ngữ cảnh, gửi biểu mẫu, điều hướng liên kết, v.v., ngoài việc hiển thị trang.
Kiểm tra tích hợp
Kiểm thử tích hợp giúp kiểm tra ứng dụng dưới dạng mô-đun thay vì kiểm tra từng trang riêng lẻ như trong kiểm thử đơn vị. Trong thử nghiệm Tích hợp, nhiều mô-đun có thể được thử nghiệm cùng nhau như một đơn vị. Tapestry cung cấp một thư viện nhỏ có tên làTapestry Test Utilitiesđể thực hiện kiểm tra tích hợp. Thư viện này tích hợp với công cụ kiểm tra Selenium để thực hiện kiểm tra. Thư viện cung cấp một lớp cơ sởSeleniumTestCase, khởi động và quản lý máy chủ Selenium, máy khách Selenium và Jetty Instance.
Một trong những ví dụ về thử nghiệm tích hợp như sau:
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");
}
}
Bảng điều khiển phát triển
Bảng điều khiển phát triển là trang mặc định được sử dụng để xác định / giải quyết các vấn đề trong ứng dụng của bạn. Trang tổng quan được truy cập bằng URLhttp://localhost:8080/myfirstapp/core/t5dashboard. Bảng điều khiển hiển thị tất cả các trang, dịch vụ và thư viện thành phần có sẵn trong ứng dụng.
Nén phản hồi
Tapestry tự động nén phản hồi bằng cách sử dụng GZIP compressionvà truyền trực tuyến cho khách hàng. Tính năng này sẽ giảm lưu lượng mạng và hỗ trợ phân phối trang nhanh hơn. Nén có thể được cấu hình bằng cách sử dụng biểu tượngtapestry.min-gzip-sizetrong AppModule.java. Giá trị mặc định là 100 byte. Tapestry sẽ nén phản hồi khi kích thước của phản hồi vượt qua 100 byte.
Bảo vệ
Tapestry cung cấp nhiều tùy chọn để bảo mật ứng dụng khỏi các lỗ hổng bảo mật đã biết trong ứng dụng web. Một số tùy chọn này được liệt kê bên dưới -
HTTPS - Các trang thảm có thể được chú thích bằng @Secure để biến nó thành một trang an toàn và có thể truy cập bởi https protocol chỉ có.
Page access control - Kiểm soát trang chỉ được truy cập bởi một người dùng nhất định.
White-Listed Page - Các trang thảm có thể được chú thích bằng @WhitelistAccessOnly để làm cho nó chỉ có thể truy cập thông qua localhost.
Asset Security- Dưới tấm thảm, chỉ một số loại tệp nhất định mới có thể truy cập được. Những người khác chỉ có thể được truy cập khiMD5 hash của tệp được cung cấp.
Serialized Object Date - Tapestry tích hợp HMAC vào dữ liệu đối tượng Java được tuần tự hóa và gửi đến máy khách để tránh giả mạo thông điệp.
Cross Site Request Forgery- Tapestry cung cấp một mô-đun bên thứ 3 được gọi là tapestry-csrf-Protection để ngăn chặn bất kỳ cuộc tấn công CSRF nào.
Security Framework integration- Tấm thảm không khóa vào một thực hiện xác thực / ủy quyền duy nhất. Tấm thảm có thể được tích hợp với bất kỳ khung xác thực phổ biến nào.
Ghi nhật ký
Tapestry cung cấp hỗ trợ rộng rãi cho việc ghi nhật ký, tự động ghi lại tiến trình của ứng dụng khi nó chạy. Tapestry sử dụng thư viện ghi nhật ký Java de-facto,SLF4J. Chú thích@Logcó thể nằm trong bất kỳ phương thức thành phần nào để phát ra lối vào và lối ra của phương thức và cả ngoại lệ có thể có. Ngoài ra, đối tượng trình ghi nhật ký do Tapestry cung cấp có thể được đưa vào bất kỳ thành phần nào bằng cách sử dụng@Inject chú thích như hình dưới đây -
public class MyPage {
@Inject
private Logger logger;
// . . .
void onSuccessFromForm() {
logger.info("Changes saved successfully");
}
@Log
void onValidateFromForm() {
// logic
}
}
Cuối cùng, bây giờ chúng ta có thể nói rằng Apache Tapestry mang đến những cách tốt nhất để xây dựng các ứng dụng ngắn gọn, có thể mở rộng, có thể bảo trì, mạnh mẽ và hỗ trợ Ajax. Tấm thảm có thể được tích hợp với bất kỳ ứng dụng Java nào của bên thứ ba. Nó cũng có thể giúp tạo một ứng dụng web lớn vì nó khá dễ dàng và nhanh chóng.