Apache Tapestry - คู่มือฉบับย่อ
Apache Tapestry เป็นเว็บเฟรมเวิร์กแบบโอเพนซอร์สที่เขียนด้วย Java มันคือcomponent based web framework. ส่วนประกอบ Tapestry คือ Java Classes พวกเขาไม่ได้รับมาจากคลาสฐานเฉพาะของเฟรมเวิร์กหรือการใช้งานอินเทอร์เฟซและเป็นเพียง POJO ธรรมดา (Plain old Java Objects)
คุณสมบัติที่สำคัญของ Java ที่ใช้โดย Tapestry คือ Annotation. หน้าเว็บ Tapestry สร้างขึ้นโดยใช้ส่วนประกอบอย่างน้อยหนึ่งส่วนแต่ละส่วนมีเทมเพลตที่ใช้ XML และคลาสส่วนประกอบที่ตกแต่งด้วยคำอธิบายประกอบของ Tapestry จำนวนมาก Tapestry สามารถสร้างอะไรก็ได้ตั้งแต่เว็บแอปพลิเคชันขนาดเล็กหน้าเดียวไปจนถึงเว็บขนาดใหญ่ที่มีหลายร้อยหน้า
ประโยชน์ของ Tapestry
ประโยชน์บางประการที่ได้รับจากพรม ได้แก่ -
- เว็บแอปพลิเคชันที่ปรับขนาดได้สูง
- Adaptive API
- กรอบที่รวดเร็วและเป็นผู้ใหญ่
- การจัดการการจัดเก็บสถานะถาวร
- Build-in Inversion ของการควบคุม
คุณสมบัติของ Tapestry
Tapestry มีคุณสมบัติดังต่อไปนี้ -
- โหลดคลาสสดใหม่
- การรายงานข้อยกเว้นที่ชัดเจนและละเอียด
- โครงสร้างแบบคงที่พฤติกรรมแบบไดนามิก
- การใช้งาน Plain Old Java Objects (POJO) อย่างกว้างขวาง
- รหัสน้อยส่งมอบมากขึ้น
ทำไมต้อง Tapestry?
Java มีเว็บเฟรมเวิร์กมากมายเช่น JSP, Struts ฯลฯ แล้วทำไมเราถึงต้องการเฟรมเวิร์กอื่น? Java Web Frameworks ในปัจจุบันส่วนใหญ่มีความซับซ้อนและมีช่วงการเรียนรู้ที่สูงชัน มันล้าสมัยและต้องใช้วงจรการคอมไพล์ทดสอบและปรับใช้สำหรับการอัปเดตทุกครั้ง
ในทางกลับกัน Tapestry นำเสนอแนวทางที่ทันสมัยในการเขียนโปรแกรมเว็บแอปพลิเคชันโดยการให้ live class reloading. ในขณะที่เฟรมเวิร์กอื่น ๆ กำลังแนะนำอินเทอร์เฟซนามธรรมและคลาสพื้นฐานมากมาย Tapestry เพียงแค่แนะนำชุดคำอธิบายประกอบเล็ก ๆ และยังให้ความสามารถในการเขียนแอปพลิเคชันขนาดใหญ่พร้อมการสนับสนุน AJAX
Tapestry พยายามใช้คุณสมบัติที่มีอยู่ของ Java ให้มากที่สุด ตัวอย่างเช่นหน้า Tapestry ทั้งหมดเป็นเพียง POJO ไม่บังคับใช้อินเทอร์เฟซที่กำหนดเองหรือคลาสพื้นฐานใด ๆ ในการเขียนแอปพลิเคชัน แต่จะใช้ Annotation (ตัวเลือกน้ำหนักเบาเพื่อขยายการทำงานของคลาส Java) เพื่อให้คุณสมบัติต่างๆ มันขึ้นอยู่กับการทดสอบการต่อสู้Java Servlet APIและใช้เป็นตัวกรอง Servlet เป็นมิติใหม่ให้กับเว็บแอปพลิเคชันและการเขียนโปรแกรมนั้นค่อนข้างง่ายยืดหยุ่นเข้าใจได้และมีประสิทธิภาพ
เวิร์กโฟลว์
ให้เราพิจารณาลำดับของการดำเนินการที่เกิดขึ้นเมื่อมีการร้องขอหน้าเทป
Step 1 - Java Servletได้รับการร้องขอหน้า Java Servlet นี้ได้รับการกำหนดค่าในลักษณะที่คำขอที่เข้ามาจะถูกส่งต่อไปยัง tapestry การกำหนดค่าเสร็จสิ้นในไฟล์web.xmlตามที่ระบุไว้ในโปรแกรมต่อไปนี้ แท็กตัวกรองและไส้กรองแมปเปลี่ยนเส้นทางทุกการร้องขอไปยังผ้ากรอง
<!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 - Tapestry Filter เรียกไฟล์ HttpServletRequestHandler บริการโดย Service() วิธี.
Step 3 - HttpServletRequestHandler จัดเก็บคำขอและการตอบกลับใน RequestGlobals. นอกจากนี้ยังรวมการร้องขอและการตอบกลับเป็นอ็อบเจ็กต์ Request and Response และส่งไปยัง RequestHandler
Step 4 - RequestHandler เป็นนามธรรมที่อยู่ด้านบนของ HttpServletRequestของ Servlet API คุณลักษณะเด่นบางประการของพรมทำในRequestHandlerมาตรา. คุณสมบัติของ Tapestry สามารถขยายได้โดยการเขียนตัวกรองใน RequestHandler RequestHandler มีตัวกรองในตัวหลายตัวซึ่งรวมถึง -
CheckForUpdates Filter- รับผิดชอบในการโหลดคลาสสด ตัวกรองนี้จะตรวจสอบการเปลี่ยนแปลงคลาส java และอัปเดตแอปพลิเคชันตามความจำเป็น
Localization Filter - ระบุตำแหน่งของผู้ใช้และให้การสนับสนุนการแปลสำหรับแอปพลิเคชัน
StaticFiles Filter- ระบุคำขอคงที่และยกเลิกกระบวนการ เมื่อกระบวนการถูกยกเลิก Java Servlet จะเข้าควบคุมและดำเนินการตามคำขอ
Error Filter - ตรวจจับข้อยกเว้นที่ไม่ถูกจับและแสดงหน้ารายงานข้อยกเว้น
RequestHandler ยังปรับเปลี่ยนและจัดเก็บคำร้องขอและการตอบกลับใน RequestQlobals และเรียกใช้บริการ MasterDispatcher
Step 5 - MasterDispatcherมีหน้าที่รับผิดชอบในการแสดงผลเพจโดยการเรียกผู้มอบหมายงานหลายคนเป็นคำสั่งเฉพาะ ผู้มอบหมายงานหลักสี่ตัวที่เรียกโดย MasterDispatcher มีดังต่อไปนี้ -
RootPath Dispatcher - มันรับรู้เส้นทางราก“ /” ของคำขอและแสดงผลเหมือนกับหน้าเริ่มต้น
Asset Dispatcher - รับรู้คำขอเนื้อหา (สินทรัพย์ Java) โดยตรวจสอบรูปแบบ URL / สินทรัพย์ / และส่งเนื้อหาที่ร้องขอเป็นไบต์สตรีม
PageRender Dispatcher- การดำเนินการ tapestry จำนวนมากจะทำใน PageRender Dispatcher และ Component Dispatcher ตัวถัดไป ผู้มอบหมายงานนี้รับรู้หน้าเฉพาะของคำขอนั้นและบริบทการเปิดใช้งาน (ข้อมูลเพิ่มเติม) จากนั้นจะแสดงเพจนั้นและส่งไปยังไคลเอนต์ ตัวอย่างเช่นหาก url คำขอคือ / product / 12123434 ผู้มอบหมายงานจะตรวจสอบว่ามีคลาสที่มีชื่อผลิตภัณฑ์ / 12123434 หรือไม่ หากพบจะเรียกคลาส product / 12123434 สร้างการตอบสนองและส่งไปยังไคลเอนต์ หากไม่เป็นเช่นนั้นจะตรวจสอบระดับผลิตภัณฑ์ หากพบจะเรียกคลาสผลิตภัณฑ์ที่มีข้อมูลเพิ่มเติม 121234434 สร้างการตอบสนองและส่งไปยังไคลเอนต์ ข้อมูลเพิ่มเติมนี้เรียกว่าบริบทการเปิดใช้งาน หากไม่พบคลาสก็เพียงแค่ส่งต่อการร้องขอไปยัง Component Dispatcher
Component Dispatcher- Component Dispatcher จับคู่ URL ของเพจด้วยรูปแบบ - / <class_name> / <component_id>: <event_type> / <activation_context> ตัวอย่างเช่น / product / grid: sort / asc แสดงถึงคลาสผลิตภัณฑ์คอมโพเนนต์กริดประเภท sortevent และบริบทการเปิดใช้งาน asc ที่นี่ event_type เป็นทางเลือกและหากไม่มีการระบุการดำเนินการประเภทเหตุการณ์เริ่มต้นจะถูกทริกเกอร์ โดยปกติการตอบสนองของผู้มอบหมายงานคอมโพเนนต์คือการส่งการเปลี่ยนเส้นทางไปยังไคลเอนต์ ส่วนใหญ่การเปลี่ยนเส้นทางจะตรงกับ PageRender Dispatcher ในคำขอถัดไปและการตอบกลับที่เหมาะสมจะถูกส่งไปยังไคลเอนต์
ในบทนี้เราจะพูดถึงวิธีการติดตั้ง Tapestry บนเครื่องของเรา
ข้อกำหนดเบื้องต้น
การพึ่งพาเพียงอย่างเดียวของ Tapestry คือ Core Java. Tapestry ได้รับการพัฒนาอย่างอิสระโดยไม่ต้องใช้ไลบรารี / เฟรมเวิร์กของบุคคลที่สาม แม้แต่ไลบรารี IoC ที่ใช้โดย Tapestry ก็ได้รับการพัฒนาตั้งแต่เริ่มต้น เว็บแอปพลิเคชันที่เขียนด้วยผ้าม่านสามารถสร้างและปรับใช้จากคอนโซลได้
เราสามารถใช้ Maven, Eclipse และ Jettyเพื่อปรับปรุงประสบการณ์การพัฒนา Maven มีเทมเพลตแอปพลิเคชันเริ่มต้นอย่างรวดเร็วและตัวเลือกสำหรับโฮสต์แอปพลิเคชันใน Jetty ซึ่งเป็นเซิร์ฟเวอร์การพัฒนา de-facto ของ Java Eclipse มีคุณสมบัติการจัดการโครงการที่ครอบคลุมและทำงานร่วมกับ maven ได้เป็นอย่างดี
การพัฒนาแอปพลิเคชัน Tapestry ในอุดมคติต้องการสิ่งต่อไปนี้ -
- Java 1.6 หรือใหม่กว่า
- Apache Maven
- Eclipse IDE
- เซิร์ฟเวอร์ท่าเทียบเรือ
ตรวจสอบการติดตั้ง Maven
หวังว่าคุณได้ติดตั้ง Maven บนเครื่องของคุณแล้ว ในการตรวจสอบการติดตั้ง Maven ให้พิมพ์คำสั่งที่ระบุด้านล่าง -
mvn --version
คุณสามารถดูการตอบสนองดังที่แสดงด้านล่าง -
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-1110T22:11:47+05:30)
Maven home: /Users/workspace/maven/apache-maven-3.3.9
Java version: 1.8.0_92, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.4", arch: "x86_64", family: "mac"
หากไม่ได้ติดตั้ง Maven ให้ดาวน์โหลดและติดตั้ง maven เวอร์ชันล่าสุดโดยไปที่เว็บไซต์Maven
ดาวน์โหลด Tapestry
Tapestryเวอร์ชันล่าสุดคือ 5.4 และสามารถดาวน์โหลดได้จากเว็บไซต์Tapestry ก็เพียงพอที่จะดาวน์โหลดแพ็คเกจไบนารี หากเราใช้ Maven Quick Start Template ก็ไม่จำเป็นต้องดาวน์โหลด Tapestry แยกต่างหาก Maven จะดาวน์โหลด Tapestry Jars ที่จำเป็นโดยอัตโนมัติและกำหนดค่าแอปพลิเคชัน เราจะพูดถึงวิธีการสร้าง Tapestry Application พื้นฐานโดยใช้ Maven ในบทถัดไป
หลังจากติดตั้ง Tapestry ให้เราสร้างโปรเจ็กต์เริ่มต้นใหม่โดยใช้ Maven ดังที่แสดงด้านล่าง -
$ mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org
คุณสามารถดูการตอบสนองดังที่แสดงด้านล่าง -
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ---------------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) >
generatesources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.4:generate (default-cli)
< generatesources @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart
(org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
หลังจาก Maven สร้างการดำเนินการทั้งหมดแล้วให้เลือกแม่แบบที่จะสร้าง Tapestry 5 QuickStart โครงการดังนี้ -
Choose archetype -
https://tapestry.apache.org → org.apache.tapestry: การเริ่มต้นอย่างรวดเร็ว (โครงการ Tapestry 5 Quickstart)
https://tapestry.apache.org → org.apache.tapestry: tapestry-archetype (Tapestry 4.1.6 Archetype)
เลือกตัวเลขหรือใช้ตัวกรอง (รูปแบบ: [groupId:] artifactId, case sensitive contains): 1
ตอนนี้คุณจะได้รับคำตอบเช่นเดียวกับที่แสดงด้านล่าง -
Choose org.apache.tapestry:quickstart version:
1: 5.0.19
2: 5.1.0.5
3: 5.2.6
4: 5.3.7
5: 5.4.1
แตกหมายเลขเวอร์ชัน QuickStart ดังต่อไปนี้ -
Choose a number: 5: 5
ที่นี่โครงการ QuickStart ใช้เวอร์ชันสำหรับตัวเลือก 5 คือ“ 5.4.1” ตอนนี้แม่แบบ Tapestry จะถามข้อมูลต่อไปนี้ทีละรายการดังนี้ -
5.1 groupId - กำหนดค่าสำหรับคุณสมบัติ 'groupId':: com.example
5.2 artifactId - กำหนดมูลค่าสำหรับคุณสมบัติ 'artifactId':: Myapp
5.3 version - กำหนดมูลค่าสำหรับคุณสมบัติ 'เวอร์ชัน': 1.0-SNAPSHOT::
5.4 package name - กำหนดค่าสำหรับคุณสมบัติ 'package': com.example:: com.example.Myapp
ตอนนี้หน้าจอของคุณขอการยืนยันจากคุณ -
ยืนยันการกำหนดค่าคุณสมบัติ -
groupId - com.example
artifactId - Myapp
version - 1.0-SNAPSHOT
package - com.example.Myapp
ตรวจสอบคุณสมบัติทั้งหมดและยืนยันการเปลี่ยนแปลงโดยใช้ตัวเลือกที่แสดงด้านล่าง -
Y: : Y
คุณจะเห็นหน้าจอเหมือนกับที่แสดงด้านล่าง
[INFO] ---------------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: quickstart:5.4.1
[INFO] ---------------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: Myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.example.Myapp
[INFO] Parameter: packageInPathFormat, Value: com/example/Myapp
[INFO] Parameter: package, Value: com.example.Myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: Myapp
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/java
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/main/webapp
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/main/resources/com/
example/Myapp
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/resource
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/test/conf
[WARNING] Don't override file /Users/workspace/tapestry/Myapp/src/site
[INFO] project created from Archetype in dir: /Users/workspace/tapestry/Myapp
[INFO] ---------------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ---------------------------------------------------------------------------------
[INFO] Total time: 11:28 min
[INFO] Finished at: 2016-09-14T00:47:23+05:30
[INFO] Final Memory: 14M/142M
[INFO] ---------------------------------------------------------------------------------
คุณได้สร้างโครงการ Tapestry Quick Start เรียบร้อยแล้ว ย้ายไปยังตำแหน่งที่สร้างขึ้นใหม่Myapp ไดเร็กทอรีด้วยคำสั่งต่อไปนี้และเริ่มการเข้ารหัส
cd Myapp
เรียกใช้แอปพลิเคชัน
ในการรันโครงกระดูกให้ใช้คำสั่งต่อไปนี้
mvn jetty:run -Dtapestry.execution-mode=development
คุณจะได้หน้าจอแบบนี้
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------------------------------------------------------------
[INFO] Building Myapp Tapestry 5 Application 1.0-SNAPSHOT
[INFO] ---------------------------------------------------------------------------------
........
........
........
Application 'app' (version 1.0-SNAPSHOT-DEV) startup time: 346 ms to build IoC
Registry, 1,246 ms overall.
______ __ ____
/_ __/__ ____ ___ ___ / /_______ __ / __/
/ / / _ `/ _ \/ -_|_-</ __/ __/ // / /__ \
/_/ \_,_/ .__/\__/___/\__/_/ \_, / /____/
/_/ /___/ 5.4.1 (development mode)
[INFO] Started [email protected]:8080
[INFO] Started Jetty Server
ณ ตอนนี้เราได้สร้างโครงการ Quick Start พื้นฐานใน Tapestry หากต้องการดูแอปพลิเคชันที่กำลังทำงานอยู่ในเว็บเบราว์เซอร์เพียงพิมพ์ URL ต่อไปนี้ในแถบที่อยู่แล้วกด Enter -
https://localhost:8080/myapp
ที่นี่ myapp คือชื่อของแอปพลิเคชันและพอร์ตเริ่มต้นของแอปพลิเคชันในโหมดการพัฒนาคือ 8080
ใช้ Eclipse
ในบทที่แล้วเราได้พูดถึงวิธีสร้างแอปพลิเคชัน Tapestry Quick Start ใน CLI บทนี้จะอธิบายเกี่ยวกับการสร้างแอปพลิเคชันโครงกระดูกในEclipse IDE.
ให้เราใช้แม่แบบ Maven เพื่อสร้างแอปพลิเคชันโครงกระดูก ในการกำหนดค่าแอปพลิเคชันใหม่คุณสามารถทำตามขั้นตอนด้านล่างนี้
ขั้นตอนที่ 1: เปิด Eclipse IDE
เปิด Eclipse ของคุณและเลือก File → New → Project …→ตัวเลือกดังที่แสดงในภาพหน้าจอต่อไปนี้
ตอนนี้เลือกตัวเลือกโครงการ Maven → Maven
Note - หากไม่ได้กำหนดค่า Maven ให้กำหนดค่าและสร้างโครงการ
หลังจากเลือกโครงการ Maven ให้คลิกถัดไปแล้วคลิกปุ่มถัดไปอีกครั้ง
หลังจากนั้นคุณจะได้รับหน้าจอที่คุณควรเลือกตัวเลือกกำหนดค่า เมื่อกำหนดค่าแล้วคุณจะได้รับหน้าจอต่อไปนี้
ขั้นตอนที่ 2: การกำหนดค่าแค็ตตาล็อก
หลังจากขั้นตอนแรกเสร็จสิ้นคุณควรคลิกที่ Add Remote Catalog. จากนั้นเพิ่มการเปลี่ยนแปลงต่อไปนี้ตามที่แสดงในภาพหน้าจอต่อไปนี้
ตอนนี้มีการเพิ่ม Apache Tapestry Catalog จากนั้นเลือกตัวเลือกกรอง org.apache.tapestry quickstart 5.4.1 ดังที่แสดงด้านล่าง
จากนั้นคลิกถัดไปและหน้าจอต่อไปนี้จะปรากฏขึ้น
ขั้นตอนที่ 3: กำหนดค่า GroupId, ArtifactId, เวอร์ชันและแพ็คเกจ
เพิ่มการเปลี่ยนแปลงต่อไปนี้ในการกำหนดค่า Tapestry Catalog
จากนั้นคลิกปุ่มเสร็จสิ้นตอนนี้เราได้สร้างแอปพลิเคชั่นโครงกระดูกตัวแรกแล้ว ในครั้งแรกที่คุณใช้ Maven การสร้างโปรเจ็กต์อาจใช้เวลาสักครู่เนื่องจาก Maven ดาวน์โหลดการอ้างอิง JAR จำนวนมากสำหรับ Maven, Jetty และ Tapestry หลังจาก Maven เสร็จสิ้นคุณจะเห็นไดเร็กทอรีใหม่ MyFirstApplication ในมุมมอง Package Explorer ของคุณ
ขั้นตอนที่ 4: เรียกใช้แอปพลิเคชันโดยใช้เซิร์ฟเวอร์ Jetty
คุณสามารถใช้ Maven เพื่อเรียกใช้ Jetty ได้โดยตรง คลิกขวาที่โครงการ MyFirstApplication ในมุมมอง Package Explorer ของคุณแล้วเลือก Run As → Maven Build …คุณจะเห็นหน้าจอด้านล่าง
ในกล่องโต้ตอบการกำหนดค่าให้ป้อนตัวเลือกเป้าหมายเป็น“ ท่าเทียบเรือ: วิ่ง” จากนั้นคลิกปุ่มเรียกใช้
เมื่อเริ่มต้น Jetty แล้วคุณจะเห็นหน้าจอต่อไปนี้ในคอนโซลของคุณ
ขั้นตอนที่ 5: เรียกใช้ในเว็บเบราว์เซอร์
พิมพ์ URL ต่อไปนี้เพื่อเรียกใช้แอปพลิเคชันในเว็บเบราว์เซอร์ -
https://loclhost:8080/MyFirstApplication
ขั้นตอนที่ 6: หยุดเซิร์ฟเวอร์ Jetty
หากต้องการหยุดเซิร์ฟเวอร์ Jetty ให้คลิกไอคอนสี่เหลี่ยมสีแดงในคอนโซลของคุณดังที่แสดงด้านล่าง
นี่คือเค้าโครงของซอร์สโค้ดที่สร้างโดย Maven Quickstart CLI. นอกจากนี้นี่คือรูปแบบที่แนะนำของ Tapestry Application มาตรฐาน
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── MyFirstApplication
│ │ │ ├── components
│ │ │ ├── data
│ │ │ ├── entities
│ │ │ ├── pages
│ │ │ └── services
│ │ ├── resources
│ │ │ ├── com
│ │ │ │ └── example
│ │ │ │ └── MyFirstApplication
│ │ │ │ ├── components
│ │ │ │ ├── logback.xml
│ │ │ │ └── pages
│ │ │ │ └── Index.properties
│ │ │ ├── hibernate.cfg.xml
│ │ │ └── log4j.properties
│ │ └── webapp
│ │ ├── favicon.ico
│ │ ├── images
│ │ │ └── tapestry.png
│ │ ├── mybootstrap
│ │ │ ├── css
│ │ │ │ ├── bootstrap.css
│ │ │ │ └── bootstrap-theme.css
│ │ │ ├── fonts
│ ├── glyphicons-halflings-regular.eot
│ │ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ │ └── glyphicons-halflings-regular.woff2
│ │ │ └── js
│ │ └── WEB-INF
│ │ ├── app.properties
│ │ └── web.xml
│ ├── site
│ │ ├── apt
│ │ │ └── index.apt
│ │ └── site.xml
│ └── test
│ ├── conf
│ │ ├── testng.xml
│ │ └── webdefault.xml
│ ├── java
│ │ └── PLACEHOLDER
│ └── resources
│ └── PLACEHOLDER
└── target
├── classes
│ ├── com
│ │ └── example
│ │ └── MyFirstApplication
│ │ ├── components
│ │ ├── data
│ │ ├── entities
│ │ ├── logback.xml
│ │ ├── pages
│ │ │ └── Index.properties
│ │ └── services
│ ├── hibernate.cfg.xml
│ └── log4j.properties
├── m2e-wtp
│ └── web-resources
│ └── META-INF
│ ├── MANIFEST.MF
│ └── maven
│ └── com.example
│ └──MyFirstApplication
│ ├── pom.properties
│ └── pom.xml
├── test-classes
│ └── PLACEHOLDER
└── work
├── jsp
├── sampleapp.properties
└── sampleapp.script
เค้าโครงเริ่มต้นถูกจัดเรียงเหมือนไฟล์ WAR Internal File Format. การใช้รูปแบบ WAR ช่วยในการรันแอปพลิเคชันโดยไม่ต้องบรรจุหีบห่อและปรับใช้ เลย์เอาต์นี้เป็นเพียงข้อเสนอแนะ แต่สามารถจัดเรียงแอปพลิเคชันในรูปแบบใดก็ได้หากบรรจุในรูปแบบ WAR ที่เหมาะสมขณะปรับใช้
ซอร์สโค้ดสามารถแบ่งออกเป็นสี่ส่วนหลักดังต่อไปนี้
Java Code - ซอร์สโค้ด java ทั้งหมดอยู่ภายใต้ /src/main/javaโฟลเดอร์ ชั้นเรียนของ Tapestry อยู่ภายใต้โฟลเดอร์“ Pages” และชั้นเรียนส่วนประกอบของ Tapestry จะอยู่ในโฟลเดอร์ส่วนประกอบ คลาสบริการ Tapestry อยู่ในโฟลเดอร์บริการ
ClassPath Resources- ใน Tapestry คลาสส่วนใหญ่มีทรัพยากรที่เกี่ยวข้อง (เทมเพลต XML ไฟล์ JavaScript ฯลฯ ) ทรัพยากรเหล่านี้อยู่ภายใต้/src/main/resourcesโฟลเดอร์ Tapestry Page Classes มีทรัพยากรที่เกี่ยวข้องภายใต้โฟลเดอร์“ Pages” และคลาสส่วนประกอบของ Tapestry มีทรัพยากรที่เกี่ยวข้องภายใต้โฟลเดอร์ Components ทรัพยากรเหล่านี้รวมอยู่ในไฟล์WEB-INF/classes โฟลเดอร์ของ WAR.
Context Resources - เป็นทรัพยากรแบบคงที่ของเว็บแอปพลิเคชันเช่นรูปภาพสไตล์ชีตและไลบรารี JavaScript / Modules. They are usually placed under the /src/main/webapp โฟลเดอร์และเรียกว่า Context Resources. นอกจากนี้ไฟล์คำอธิบายเว็บแอปพลิเคชัน (ของ Java Servlet), web.xml จะอยู่ใต้ไฟล์WEB-INF โฟลเดอร์ของทรัพยากรบริบท
Testing Code - ไฟล์เหล่านี้เป็นไฟล์เสริมที่ใช้ในการทดสอบแอปพลิเคชันและวางไว้ใต้ไฟล์ src/test/java และ src/test/โฟลเดอร์ทรัพยากร ไม่ได้บรรจุใน WAR
Apache Tapestry ดังต่อไปนี้ Convention over Configurationในทุกแง่มุมของการเขียนโปรแกรม ทุกคุณลักษณะของกรอบมีหลักการเริ่มต้นที่เหมาะสม
ตัวอย่างเช่นตามที่เราเรียนรู้ในบทเค้าโครงโครงการทุกหน้าจะต้องอยู่ในไฟล์ /src/main/java/«package_path»/pages/ โฟลเดอร์ที่จะถือว่าเป็น Tapestry Pages
ในอีกแง่หนึ่งไม่จำเป็นต้องกำหนดค่า Java Class โดยเฉพาะเป็น Tapestry Pages ก็เพียงพอที่จะวางชั้นเรียนในตำแหน่งที่กำหนดไว้ล่วงหน้า ในบางกรณีเป็นเรื่องแปลกที่จะปฏิบัติตามหลักการเริ่มต้นของ Tapestry
ตัวอย่างเช่นส่วนประกอบ Tapestry สามารถมีวิธีการ setupRenderซึ่งจะเริ่มทำงานเมื่อเริ่มขั้นตอนการแสดงผล นักพัฒนาอาจต้องการใช้ชื่อที่เปิดขึ้นเองพูดinitializeValue. ในสถานการณ์นี้ Tapestry ให้Annotation เพื่อลบล้างข้อตกลงตามที่แสดงในบล็อกโค้ดต่อไปนี้
void setupRender() {
// initialize component
}
@SetupRender
void initializeValue() {
// initialize component
}
การเขียนโปรแกรมทั้งสองวิธีใช้ได้ใน Tapestry ในระยะสั้นการกำหนดค่าเริ่มต้นของ Tapestry นั้นค่อนข้างน้อย เพียงApache Tapestry Filter (Java Servlet Filter) จำเป็นต้องกำหนดค่าใน“ Web.xml” เพื่อให้แอปพลิเคชันทำงานได้อย่างเหมาะสม
Tapestry เป็นอีกวิธีหนึ่งในการกำหนดค่าแอปพลิเคชันและเรียกว่าเป็นไฟล์ AppModule.java.
คำอธิบายประกอบเป็นคุณสมบัติที่สำคัญมากที่ Tapestry ใช้เพื่อลดความซับซ้อนของการพัฒนาเว็บแอปพลิเคชัน Tapestry มีคำอธิบายประกอบแบบกำหนดเองมากมาย มีคำอธิบายประกอบสำหรับชั้นเรียนวิธีการและฟิลด์สมาชิก ตามที่กล่าวไว้ในหัวข้อก่อนหน้าคำอธิบายประกอบอาจใช้เพื่อลบล้างรูปแบบเริ่มต้นของคุณลักษณะ คำอธิบายประกอบ Tapestry แบ่งออกเป็นสี่ประเภทหลักและมีดังต่อไปนี้
คำอธิบายประกอบส่วนประกอบ
ใช้ใน Pages, Components และ Mixins Classes คำอธิบายประกอบที่มีประโยชน์บางส่วน ได้แก่ -
@Property- ใช้ได้กับเขตข้อมูล ใช้ในการแปลงฟิลด์เป็น Tapestry Property
@Parameter- ใช้ได้กับเขตข้อมูล ใช้เพื่อระบุฟิลด์เป็นพารามิเตอร์ของคอมโพเนนต์
@Environmental- ใช้ได้กับเขตข้อมูล ใช้เพื่อแชร์ฟิลด์ส่วนตัวระหว่างส่วนประกอบต่างๆ
@import- ใช้ได้กับคลาสและฟิลด์ ใช้เพื่อรวม Assets, CSS และ JavaScript
@Path - ใช้ร่วมกับคำอธิบายประกอบ @Inject เพื่อฉีดสินทรัพย์ตามเส้นทาง
@Log- ใช้ได้กับคลาสและฟิลด์ ใช้เพื่อวัตถุประสงค์ในการดีบัก สามารถใช้ปล่อยข้อมูลเหตุการณ์ของคอมโพเนนต์เช่นการเริ่มเหตุการณ์การสิ้นสุดของเหตุการณ์เป็นต้น
คำอธิบายประกอบ IoC
ใช้ในการฉีดวัตถุลงในคอนเทนเนอร์ IoC คำอธิบายประกอบที่มีประโยชน์บางส่วน ได้แก่ -
@Inject- ใช้ได้กับเขตข้อมูล ใช้เพื่อทำเครื่องหมายพารามิเตอร์ที่ควรฉีดลงในคอนเทนเนอร์ IoC มันทำเครื่องหมายฟิลด์ที่ควรฉีดเข้าไปในส่วนประกอบ
@Value- ใช้ได้กับเขตข้อมูล ใช้ร่วมกับคำอธิบายประกอบ @inject เพื่อแทรกค่าตามตัวอักษรแทนบริการ (ซึ่งเป็นลักษณะการทำงานเริ่มต้นของคำอธิบายประกอบ @Inject)
คำอธิบายประกอบสำหรับคลาสการเก็บข้อมูล
ใช้เพื่อระบุข้อมูลเฉพาะขององค์ประกอบในคลาส (โดยปกติจะเป็นโมเดลหรือคลาสการเก็บข้อมูล) สำหรับส่วนประกอบระดับสูงเช่น
Grid (ใช้ในการสร้างข้อมูลตารางขั้นสูงเช่นรายงานแกลเลอรี ฯลฯ )
BeanEditForm (ใช้เพื่อสร้างแบบฟอร์มขั้นสูง)
Hibernate (ใช้ในการเข้าถึงฐานข้อมูลขั้นสูง) ฯลฯ
คำอธิบายประกอบเหล่านี้ถูกรวมและบรรจุลงในโถแยกต่างหากโดยไม่ต้องพึ่งพาสิ่งทอใด ๆ คำอธิบายประกอบบางส่วน ได้แก่ -
@DataType- ใช้เพื่อระบุประเภทข้อมูลของฟิลด์ ส่วนประกอบ Tapestry อาจใช้ข้อมูลนี้เพื่อสร้างการออกแบบหรือมาร์กอัปในเลเยอร์การนำเสนอ
@Validate - ใช้เพื่อระบุกฎการตรวจสอบสำหรับฟิลด์
การแยกเหล่านี้ทำให้แอปพลิเคชัน Tapestry สามารถใช้ไฟล์ Multi-Tier Design.
Tapestry Application เป็นชุดของ Tapestry Pages พวกเขาทำงานร่วมกันเพื่อสร้าง Web Application ที่กำหนดไว้อย่างดี แต่ละหน้าจะมีเทมเพลต XML ที่สอดคล้องกันและ Zero ส่วนประกอบอย่างน้อยหนึ่งรายการ เพจและคอมโพเนนต์จะเหมือนกันยกเว้นว่าเพจเป็นส่วนประกอบหลักและมักสร้างโดยนักพัฒนาแอปพลิเคชัน
Components are children of the root Pagecomponent. Tapestry มีส่วนประกอบในตัวมากมายและมีตัวเลือกในการสร้างส่วนประกอบที่กำหนดเอง
หน้า
ตามที่กล่าวไว้ก่อนหน้านี้ Pages เป็นส่วนประกอบของ Tapestry Application เพจเป็น POJO ธรรมดาวางไว้ใต้ -/src/main/java/«package_path»/pages/โฟลเดอร์ ทุกหน้าจะมีข้อมูลที่ตรงกันXML Template และตำแหน่งเริ่มต้นคือ - /src/main/resources/«package_name»/pages/.
คุณสามารถดูได้ที่นี่ว่าโครงสร้างพา ธ คล้ายกันสำหรับเพจและเทมเพลตยกเว้นว่าเทมเพลตอยู่ในไฟล์ Resource Folder.
ตัวอย่างเช่นหน้าลงทะเบียนผู้ใช้ในแอปพลิเคชัน Tapestry ที่มีชื่อแพ็คเกจ - com.example.MyFirstApplication จะมีไฟล์ Page และ Template ต่อไปนี้ -
Java Class -
/src/main/java/com/example/MyFirstApplication/pages/index.java
XML Template -
/src/main/resources/com/example/MyFirstApplication/pages/index.tml
ให้เราสร้างไฟล์ Hello Worldหน้า. ขั้นแรกเราต้องสร้างไฟล์Java Class ที่ - /src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java”
package com.example.MyFirstApplication.pages;
public class HelloWorld {
}
จากนั้นสร้างเทมเพลต XML ที่ -
“ /src/main/resources/com/example/MyFirstApplication/pages/helloworld.html”
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>Hello World Page</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
ตอนนี้สามารถเข้าถึงหน้านี้ได้ที่ https://localhost:8080/myapp/helloworld. นี่คือหน้า Tapestry ง่ายๆ Tapestry มีคุณสมบัติเพิ่มเติมมากมายในการพัฒนาเว็บเพจแบบไดนามิกซึ่งเราจะพูดถึงในบทต่อไปนี้
ให้เราพิจารณาเทมเพลต XML ของ Tapestry ในส่วนนี้ XML Template คือเอกสาร XML ที่มีรูปแบบสมบูรณ์ เลเยอร์การนำเสนอ (ส่วนติดต่อผู้ใช้) ของเพจคือเทมเพลต XML เทมเพลต XML มีมาร์กอัป HTML ปกตินอกเหนือจากรายการที่ระบุด้านล่าง -
- เนมสเปซ Tapestry
- Expansions
- Elements
- Components
ตอนนี้ให้เราพูดคุยในรายละเอียด
เนมสเปซ Tapestry
Tapestry Namespaces ไม่ใช่อะไรนอกจากเนมสเปซ XML ควรกำหนดเนมสเปซในองค์ประกอบรากของเทมเพลต ใช้เพื่อรวมส่วนประกอบของ Tapestry และข้อมูลที่เกี่ยวข้องกับส่วนประกอบในเทมเพลต เนมสเปซที่ใช้บ่อยที่สุดมีดังนี้ -
xmlns: t =“ https://tapestry.apache.org/schema/tapestry_5_4.xsd” - ใช้เพื่อระบุองค์ประกอบส่วนประกอบและคุณสมบัติของ Tapestry
xmlns: p =“ tapestry: parameter” - ใช้เพื่อส่งโค้ดไปยังส่วนประกอบต่างๆโดยพลการ
ตัวอย่างของ Tapestry Namespace มีดังนี้ -
<html xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p = "tapestry:parameter">
<head>
<title>Hello World Page</title>
</head>
<body>
<h1>Hello World</h1>
<t:eventlink page = "Index">refresh page</t:eventlink>
</body>
</html>
การขยาย
การขยายเป็นวิธีการที่ง่ายและมีประสิทธิภาพในการเปลี่ยนเทมเพลต XML แบบไดนามิกระหว่างขั้นตอนการแสดงผลของเพจ การขยายใช้ไวยากรณ์ $ {<name>} มีตัวเลือกมากมายในการแสดงการขยายในเทมเพลต XML ให้เราดูตัวเลือกที่ใช้บ่อยที่สุด -
การขยายทรัพย์สิน
แมปคุณสมบัติที่กำหนดไว้ในคลาสเพจที่เกี่ยวข้อง เป็นไปตามข้อกำหนด Java Bean สำหรับนิยามคุณสมบัติในคลาส Java ก้าวไปอีกขั้นโดยละเว้นกรณีสำหรับชื่อคุณสมบัติ ให้เราเปลี่ยนตัวอย่าง“ Hello World” โดยใช้การขยายคุณสมบัติ บล็อกโค้ดต่อไปนี้คือคลาสเพจที่แก้ไข
package com.example.MyFirstApplication.pages;
public class HelloWorld {
// Java Bean Property
public String getName {
return "World!";
}
}
จากนั้นเปลี่ยนเทมเพลต XML ที่เกี่ยวข้องดังที่แสดงด้านล่าง
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>Hello World Page</title>
</head>
<body>
<!-- expansion -->
<h1>Hello ${name}</h1>
</body>
</html>
ที่นี่เราได้กำหนด name เช่น Java Bean Property ในคลาสเพจและประมวลผลแบบไดนามิกในเทมเพลต XML โดยใช้ส่วนขยาย ${name}.
การขยายข้อความ
แต่ละคลาสของเพจอาจมีหรือไม่มีไฟล์คุณสมบัติที่เกี่ยวข้อง - «page_name».propertiesในโฟลเดอร์ทรัพยากร ไฟล์คุณสมบัติเป็นไฟล์ข้อความธรรมดาที่มีคู่คีย์ / ค่าเดียว (ข้อความ) ต่อบรรทัด ให้เราสร้างไฟล์คุณสมบัติสำหรับ HelloWorld Page ที่ -
“ /src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties” และเพิ่มข้อความ“ Greeting”
Greeting = Hello
Greeting สามารถใช้ข้อความในเทมเพลต XML เป็น ${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>
องค์ประกอบ
Tapestry มีองค์ประกอบชุดเล็ก ๆ ที่จะใช้ในเทมเพลต XML องค์ประกอบคือแท็กที่กำหนดไว้ล่วงหน้าซึ่งกำหนดไว้ภายใต้เนมสเปซ Tapestry -
https://tapestry.apache.org/schema/tapestry_5_4.xsd
แต่ละองค์ประกอบถูกสร้างขึ้นเพื่อวัตถุประสงค์เฉพาะ องค์ประกอบพรมที่มีอยู่มีดังนี้ -
<t: body>
เมื่อคอมโพเนนต์สองคอมโพเนนต์ซ้อนกันเทมเพลตของคอมโพเนนต์หลักอาจต้องห่อเทมเพลตของคอมโพเนนต์ย่อย องค์ประกอบ <t: body> มีประโยชน์ในสถานการณ์นี้ หนึ่งในการใช้ <t: body> อยู่ในเค้าโครงเทมเพลต
โดยทั่วไปส่วนต่อประสานผู้ใช้ของเว็บแอปพลิเคชันจะมี Common Header, Footer, Menu เป็นต้นรายการทั่วไปเหล่านี้ถูกกำหนดไว้ในเทมเพลต XML และเรียกว่า Template Layout หรือ Layout Component ใน Tapestry จำเป็นต้องสร้างโดยนักพัฒนาแอปพลิเคชัน Layout Component เป็นเพียงส่วนประกอบอื่นและอยู่ภายใต้โฟลเดอร์ Components ซึ่งมีเส้นทางต่อไปนี้ -src/main/«java|resources»/«package_name»/components.
ให้เราสร้างองค์ประกอบเค้าโครงอย่างง่ายที่เรียกว่า MyCustomLayout. รหัสสำหรับ MyCustomLayout มีดังนี้ -
<!DOCTYPE html>
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<meta charset = "UTF-8" />
<title>${title}</title>
</head>
<body>
<div>Sample Web Application</div>
<h1>${title}</h1>
<t:body/>
<div>(C) 2016 TutorialsPoint.</div>
</body>
</html>
package com.example.MyFirstApplication.components;
import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.BindingConstants;
public class MyCustomLayout {
@Property
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String title;
}
ในคลาสคอมโพเนนต์ MyCustomLayout เราได้ประกาศฟิลด์ชื่อเรื่องและโดยใช้คำอธิบายประกอบเราได้กำหนดให้เป็นข้อบังคับ ตอนนี้เปลี่ยนเทมเพลต HelloWorld.html เพื่อใช้เค้าโครงที่กำหนดเองของเราดังที่แสดงในบล็อกโค้ดด้านล่าง
<html>
t:type = "mycustomlayout" title = "Hello World Test page"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<h1>${message:greeting} ${name}</h1>
</html>
เราจะเห็นได้ที่นี่ว่าเทมเพลต XML ไม่มีแท็ก head and body Tapestry จะรวบรวมรายละเอียดเหล่านี้จากองค์ประกอบเค้าโครงและ <t: body> ขององค์ประกอบเค้าโครงจะถูกแทนที่ด้วยเทมเพลต HelloWorld เมื่อทุกอย่างเสร็จสิ้น Tapestry จะปล่อยมาร์กอัปที่คล้ายกันตามที่ระบุด้านล่าง -
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8" />
<title>Hello World Test Page</title>
</head>
<body>
<div>Sample Web Application</div>
<h1>Hello World Test Page</h1>
<h1>Hello World!</h1>
<div>(C) 2016 TutorialsPoint.</div>
</body>
</html>
เลย์เอาต์สามารถซ้อนกันได้ ตัวอย่างเช่นเราอาจขยายรูปแบบที่กำหนดเองของเราโดยรวมฟังก์ชันการดูแลระบบและใช้สำหรับส่วนผู้ดูแลระบบตามที่ระบุไว้ด้านล่าง
<html t:type = "MyCommonLayout"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<div><!-- Admin related items --><div>
<t:body/>
</html>
<t: container>
<t: container> เป็นองค์ประกอบระดับบนสุดและมีเนมสเปซแบบ tapestry ใช้เพื่อระบุส่วนไดนามิกของส่วนประกอบ
ตัวอย่างเช่นคอมโพเนนต์กริดอาจต้องใช้เทมเพลตเพื่อระบุวิธีการแสดงผลแถว - tr (และคอลัมน์ td) ภายในตาราง HTML
<t:container xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<td>${name}</td>
<td>${age}</td>
</t:container>
<t: block>
<t: block> เป็นตัวยึดสำหรับส่วนไดนามิกในเทมเพลต โดยทั่วไปองค์ประกอบบล็อกจะไม่แสดงผล เฉพาะส่วนประกอบที่กำหนดในเทมเพลตเท่านั้นที่ใช้องค์ประกอบบล็อก คอมโพเนนต์จะฉีดข้อมูลแบบไดนามิกลงในองค์ประกอบบล็อกและแสดงผล หนึ่งในกรณีการใช้งานที่เป็นที่นิยมคือAJAX.
องค์ประกอบบล็อกให้ตำแหน่งที่แน่นอนและมาร์กอัปสำหรับข้อมูลไดนามิกที่จะแสดงผล ทุกองค์ประกอบของบล็อกควรมีคุณสมบัติ Java ที่สอดคล้องกัน จากนั้นจึงสามารถแสดงผลแบบไดนามิกได้ id ขององค์ประกอบบล็อกควรเป็นไปตามกฎตัวระบุตัวแปร Java ตัวอย่างบางส่วนมีให้ด้านล่าง
@Inject
private Block block;
<html t:type = "mycustomlayout" title = "block example"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h1>${title}</h1>
<!--
...
...
-->
<t:block t:id = "block">
<h2>Highly dynamic section</h2>
I'v been updated through AJAX call
The current time is: <strong>${currentTime}</strong>
</t:block>
<!--
...
...
-->
</html>
<t: content>
องค์ประกอบ <t: content> ใช้เพื่อระบุเนื้อหาจริงของเทมเพลต โดยทั่วไปแล้วมาร์กอัปทั้งหมดถือเป็นส่วนหนึ่งของเทมเพลต หากระบุ <t: content> ระบบจะพิจารณาเฉพาะมาร์กอัปภายในเท่านั้น ฟีเจอร์นี้ถูกใช้โดยนักออกแบบเพื่อออกแบบเพจโดยไม่มีองค์ประกอบเค้าโครง
<t: ลบ>
<t: remove> อยู่ตรงข้ามกับองค์ประกอบเนื้อหา มาร์กอัปภายในองค์ประกอบการลบไม่ถือเป็นส่วนหนึ่งของเทมเพลต สามารถใช้สำหรับความคิดเห็นของเซิร์ฟเวอร์เท่านั้นและเพื่อวัตถุประสงค์ในการออกแบบ
สินทรัพย์
เนื้อหาคือไฟล์ทรัพยากรแบบคงที่เช่นสไตล์ชีตรูปภาพและไฟล์ JavaScript โดยทั่วไปเนื้อหาจะอยู่ในไดเรกทอรีรากของเว็บแอปพลิเคชัน/src/main/webapp.
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestry ยังจัดการไฟล์ที่เก็บไว้ในไฟล์ Java Classpathเป็นสินทรัพย์ Tapestry มีตัวเลือกขั้นสูงในการรวมเนื้อหาไว้ในเทมเพลตผ่านตัวเลือกการขยาย
Context - ตัวเลือกในการรับเนื้อหาที่มีอยู่ในบริบทของเว็บ
<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>
asset- ส่วนประกอบมักจะเก็บทรัพย์สินของตัวเองไว้ในไฟล์ jar พร้อมกับคลาส Java เริ่มจาก Tapestry 5.4 เส้นทางมาตรฐานในการจัดเก็บเนื้อหาใน classpath คือMETA-INF/assets. สำหรับไลบรารีเส้นทางมาตรฐานในการจัดเก็บสินทรัพย์คือMETA-INF/assets/«library_name»/. asset: ยังสามารถโทร context: การขยายเพื่อรับเนื้อหาจากบริบทเว็บ
<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>
สามารถแทรกเนื้อหาลงใน Tapestry Page หรือ Component ได้โดยใช้คำอธิบายประกอบแบบ Inject และ Path พารามิเตอร์สำหรับคำอธิบายประกอบเส้นทางคือพา ธ สัมพัทธ์ของเนื้อหา
@Inject
@Path("images/edit.png")
private Asset icon;
Path parameter ยังสามารถมีสัญลักษณ์ Tapestry ที่กำหนดไว้ในไฟล์ AppModule.java มาตรา.
ตัวอย่างเช่นเราสามารถกำหนดสัญลักษณ์ skin.root ด้วยบริบทของค่า: สกิน / พื้นฐานและใช้ตามที่แสดงด้านล่าง -
@Inject
@Path("${skin.root}/style.css")
private Asset style;
การแปล
การรวมทรัพยากรผ่านผ้าม่านให้ฟังก์ชันพิเศษ หนึ่งในฟังก์ชันดังกล่าวคือ“ การแปลเป็นภาษาท้องถิ่น” Tapestry จะตรวจสอบสถานที่ปัจจุบันและรวมทรัพยากรที่เหมาะสม
ตัวอย่างเช่นหากตั้งค่าภาษาปัจจุบันเป็น deแล้ว edit_de.png จะรวมไว้แทน edit.png
CSS
Tapestry มีการรองรับสไตล์ชีตในตัว พรมจะฉีดtapestry.cssเป็นส่วนหนึ่งของสแต็ก Javascript หลัก จาก Tapestry 5.4 Tapestry รวมถึงbootstrap css frameworkเช่นกัน. เราสามารถรวมสไตล์ชีตของเราเองโดยใช้แท็กลิงก์ปกติ ในกรณีนี้สไตล์ชีตควรอยู่ในไดเรกทอรีรากของเว็บ -/src/main/webapp/.
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestry มีตัวเลือกขั้นสูงเพื่อรวมสไตล์ชีตไว้ในเทมเพลตผ่านตัวเลือกการขยายตามที่กล่าวไว้ก่อนหน้านี้
<head>
<link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>
Tapestry ยังมีคำอธิบายประกอบการนำเข้าเพื่อรวมสไตล์ชีตลงในคลาส Java โดยตรง
@Import(stylesheet="context:css/site.css")
public class MyCommonLayout {
}
Tapestry มีตัวเลือกมากมายในการจัดการสไตล์ชีตผ่าน AppModule.java บางตัวเลือกที่สำคัญ ได้แก่ -
สไตล์ชีตเริ่มต้นของ Tapestry อาจถูกลบออก
@Contribute(MarkupRenderer.class)
public static void
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) {
configuration.override("InjectDefaultStyleheet", null);
}
Bootstrap ยังสามารถปิดใช้งานได้โดยการลบล้างเส้นทาง
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
เปิดใช้งานการย่อขนาดเนื้อหาแบบไดนามิก (CSS และ JavaScript) เราจำเป็นต้องรวมtapestry-webresources การพึ่งพา (ใน pom.xml) เช่นกัน
@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void contributeApplicationDefaults(
MappedConfiguration<String, String> configuration) {
configuration.add(SymbolConstants.MINIFICATION_ENABLED, "true");
}
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-webresources</artifactId>
<version>5.4</version>
</dependency>
JavaScript ฝั่งไคลเอ็นต์
การสร้างเว็บแอปพลิเคชันในปัจจุบันขึ้นอยู่กับ JavaScript เป็นอย่างมากเพื่อมอบประสบการณ์ฝั่งไคลเอ็นต์ที่หลากหลาย Tapestry รับทราบและให้การสนับสนุนระดับเฟิร์สคลาสสำหรับ JavaScript การสนับสนุน JavaScript นั้นฝังแน่นอยู่ใน Tapestry และพร้อมใช้งานในทุกขั้นตอนของการเขียนโปรแกรม
ก่อนหน้านี้ Tapestry เคยรองรับเฉพาะ Prototype และ Scriptaculous แต่จากเวอร์ชัน 5.4 Tapestry เขียนเลเยอร์ JavaScript ใหม่ทั้งหมดเพื่อให้เป็นแบบทั่วไปที่สุดและให้การสนับสนุนระดับเฟิร์สคลาสสำหรับ JQuery ไลบรารี de-facto สำหรับ JavaScript นอกจากนี้ tapestry ยังสนับสนุนการเขียนโปรแกรม JavaScript ที่ใช้ Modules และสนับสนุน RequireJS ซึ่งเป็นการนำไปใช้งานฝั่งไคลเอ็นต์ยอดนิยมของ AMD (Asynchronous Module Definition - ข้อกำหนด JavaScript เพื่อรองรับโมดูลและการพึ่งพาในลักษณะอะซิงโครนัส)
สถานที่
ไฟล์ JavaScript เป็นทรัพย์สินของ Tapestry Application ตามกฎของเนื้อหาไฟล์ JavaScript จะถูกวางไว้ภายใต้บริบทของเว็บ/sr/main/webapp/ หรือวางไว้ในโถด้านล่าง META-INF/assets/ location.
การเชื่อมโยงไฟล์ JavaScript
วิธีที่ง่ายที่สุดในการเชื่อมโยงไฟล์ JavaScript ในเทมเพลต XML คือการใช้แท็กสคริปต์โดยตรงซึ่งก็คือ - <script language = "javascript" src = "relative/path/to/js"></script>. แต่ผ้าม่านไม่แนะนำวิธีการเหล่านี้ Tapestry มีตัวเลือกมากมายในการเชื่อมโยงไฟล์ JavaScript ใน Page / Component บางส่วนเหล่านี้ได้รับด้านล่าง
@import annotation- คำอธิบายประกอบ @import มีตัวเลือกในการเชื่อมโยงไลบรารี JavaScript หลายรายการโดยใช้นิพจน์บริบท สามารถใช้ได้กับทั้ง Page class และ method หากนำไปใช้กับคลาสเพจจะใช้กับวิธีการทั้งหมด หากใช้กับเมธอดของเพจจะใช้กับเมธอดนั้นเท่านั้นจากนั้น Tapestry จะลิงก์ไลบรารี JavaScript ก็ต่อเมื่อมีการเรียกใช้เมธอด
@Import(library = {"context:js/jquery.js","context:js/myeffects.js"})
public class MyComponent {
// ...
}
JavaScriptSupport interface - JavaScriptSupport เป็นอินเทอร์เฟซที่กำหนดโดย Tapestry และมีวิธีการ importJavaScriptLibraryเพื่อนำเข้าไฟล์ JavaScript สามารถสร้างวัตถุ JavScriptSupport ได้อย่างง่ายดายเพียงแค่ประกาศและใส่คำอธิบายประกอบด้วย @Environmental annotation
@Inject @Path("context:/js/myeffects.js")
private Asset myEffects;
@Environmental
private JavaScriptSupport javaScriptSupport;
void setupRender() {
javaScriptSupport.importJavaScriptLibrary(myEffects);
}
JavaScripSupport สามารถแทรกลงในส่วนประกอบโดยใช้ไฟล์ @Environmentalคำอธิบายประกอบ สำหรับบริการเราจำเป็นต้องใช้ไฟล์@Inject คำอธิบายประกอบหรือเพิ่มเป็นอาร์กิวเมนต์ในเมธอดตัวสร้างบริการ
@Inject
private JavaScriptSupport javaScriptSupport;
public MyServiceImpl(JavaScriptSupport support) {
// ...
}
addScript method - สิ่งนี้คล้ายกับอินเทอร์เฟซ JavaScriptSupport ยกเว้นว่าจะใช้ไฟล์ addScript วิธีการและรหัสจะถูกเพิ่มโดยตรงในผลลัพธ์ที่ด้านล่างของหน้า
void afterRender() {
javaScriptSupport.addScript(
"$('%s').observe('click', hideMe());", container.getClientId());
}
กอง JavaScript
Tapestry อนุญาตให้รวมกลุ่มของไฟล์ JavaScript และสไตล์ชีตที่เกี่ยวข้องและใช้เป็นเอนทิตีเดียว ปัจจุบัน Tapestry มีสแต็กที่ใช้ Prototype และ JQuery
นักพัฒนาสามารถพัฒนาสแต็กของตนเองได้โดยใช้ไฟล์ JavaScriptStack และลงทะเบียนในไฟล์ AppModule.java. เมื่อลงทะเบียนแล้วสามารถนำเข้าสแต็กโดยใช้ไฟล์@import คำอธิบายประกอบ
@Contribute(JavaScriptStackSource.class)
public static void addMyStack(
MappedConfiguration<String, JavaScriptStack> configuration) {
configuration.addInstance("MyStack", myStack.class);
}
@Import(stack = "MyStack")
public class myPage {
}
ตามที่กล่าวไว้ก่อนหน้านี้คอมโพเนนต์และเพจจะเหมือนกันยกเว้นว่าเพจเป็นคอมโพเนนต์รูทและมีคอมโพเนนต์ย่อยหนึ่งหรือ คอมโพเนนต์มักจะอยู่ภายในเพจและทำหน้าที่แบบไดนามิกเกือบทั้งหมดของเพจ
ส่วนประกอบ Tapestry แสดงลิงก์ HTML อย่างง่ายไปยังฟังก์ชันกริดที่ซับซ้อนด้วย interactive AJAX. ส่วนประกอบอาจรวมถึงส่วนประกอบอื่นด้วย ส่วนประกอบของ Tapestry ประกอบด้วยรายการต่อไปนี้ -
Component Class - คลาส Java หลักของคอมโพเนนต์
XML Template- เทมเพลต XML คล้ายกับเทมเพลตของเพจ คลาสคอมโพเนนต์แสดงเทมเพลตเป็นผลลัพธ์สุดท้าย ส่วนประกอบบางอย่างอาจไม่มีเทมเพลต ในกรณีนี้เอาต์พุตจะถูกสร้างขึ้นโดยคลาสคอมโพเนนต์เองโดยใช้MarkupWriter ชั้นเรียน.
Body- ส่วนประกอบที่ระบุภายในเทมเพลตเพจอาจมีมาร์กอัปแบบกำหนดเองและเรียกว่า "เนื้อหาส่วนประกอบ" หากเทมเพลตคอมโพเนนต์มี<body />จากนั้นองค์ประกอบ <body /> จะถูกแทนที่ด้วย body ของส่วนประกอบ ซึ่งคล้ายกับเค้าโครงที่กล่าวถึงก่อนหน้านี้ในส่วนเทมเพลต XML
Rendering - การเรนเดอร์เป็นกระบวนการที่แปลงเทมเพลต XML และเนื้อความของส่วนประกอบให้เป็นผลลัพธ์จริงของส่วนประกอบ
Parameters - ใช้เพื่อสร้างการสื่อสารระหว่างคอมโพเนนต์และเพจและส่งผ่านข้อมูลระหว่างกัน
Events- มอบหมายการทำงานจากคอมโพเนนต์ไปยังคอนเทนเนอร์ / พาเรนต์ (เพจหรือคอมโพเนนต์อื่น) มีการใช้กันอย่างแพร่หลายในการนำทางหน้า
การแสดงผล
การแสดงผลของคอมโพเนนต์จะทำในชุดของเฟสที่กำหนดไว้ล่วงหน้า แต่ละเฟสในระบบคอมโพเนนต์ควรมีวิธีการที่สอดคล้องกันซึ่งกำหนดโดยแบบแผนหรือคำอธิบายประกอบในคลาสคอมโพเนนต์
// Using annotaion
@SetupRender
void initializeValues() {
// initialize values
}
// using convention
boolean afterRender() {
// do logic
return true;
}
ขั้นตอนชื่อวิธีการและคำอธิบายประกอบแสดงอยู่ด้านล่าง
คำอธิบายประกอบ | ชื่อวิธีการเริ่มต้น |
---|---|
@SetupRender | setupRender () |
@BeginRender | startRender () |
@BeforeRenderTemplate | beforeRenderTemplate () |
@BeforeRenderBody | beforeRenderBody () |
@AfterRenderBody | afterRenderBody () |
@AfterRenderTemplate | afterRenderTemplate () |
@AfterRender | afterRender () |
@CleanupRender | cleanupRender () |
แต่ละขั้นตอนมีวัตถุประสงค์เฉพาะและมีดังนี้ -
SetupRender
SetupRender เริ่มกระบวนการแสดงผล โดยปกติจะตั้งค่าพารามิเตอร์ของส่วนประกอบ
BeginRender
BeginRender เริ่มแสดงผลคอมโพเนนต์ โดยปกติจะแสดงแท็กเริ่มต้น / เริ่มต้นของส่วนประกอบ
BeforeRenderTemplate
BeforeRenderTemplate ใช้ในการตกแต่งเทมเพลต XML โดยเพิ่มมาร์กอัปพิเศษรอบ ๆ เทมเพลต นอกจากนี้ยังมีตัวเลือกในการข้ามการแสดงเทมเพลต
BeforeRenderBody
BeforeRenderTemplate มีตัวเลือกในการข้ามการแสดงผลองค์ประกอบร่างกายของส่วนประกอบ
AfterRenderBody
AfterRenderBody จะถูกเรียกใช้หลังจากแสดงผลเนื้อหาของส่วนประกอบแล้ว
AfterRenderTemplate
AfterRenderTemplate จะถูกเรียกใช้หลังจากแสดงเทมเพลตของคอมโพเนนต์แล้ว
AfterRender
AfterRender เป็นคู่ของ BeginRender และมักจะแสดงผลแท็กปิด
CleanupRender
CleanupRender เป็นคู่ของ SetupRender มันเผยแพร่ / จำหน่ายวัตถุทั้งหมดที่สร้างขึ้นในระหว่างกระบวนการแสดงผล
ขั้นตอนการแสดงผลไม่ได้ไปข้างหน้าเท่านั้น มันไปมาระหว่างเฟสขึ้นอยู่กับค่าส่งกลับของเฟส
ตัวอย่างเช่นหากเมธอด SetupRender ส่งคืนค่าเท็จการแสดงผลจะข้ามไปยังเฟส CleanupRender และในทางกลับกัน หากต้องการความเข้าใจที่ชัดเจนเกี่ยวกับการไหลระหว่างระยะต่างๆให้ตรวจสอบการไหลในแผนภาพด้านล่าง
ส่วนประกอบที่เรียบง่าย
ให้เราสร้างส่วนประกอบง่ายๆสวัสดีซึ่งจะมีข้อความแสดงผลเป็น“ Hello, Tapestry” ต่อไปนี้เป็นรหัสขององค์ประกอบ Hello และเทมเพลต
package com.example.MyFirstApplication.components;
public class Hello {
}
<html
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div>
<p>Hello, Tapestry (from component).</p>
</div>
</html>
สามารถเรียกคอมโพเนนต์ Hello ในเทมเพลตเพจเป็น -
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:hello />
</html>
ในทำนองเดียวกันส่วนประกอบอาจแสดงผลลัพธ์เดียวกันโดยใช้ MarkupWriter แทนเทมเพลตดังที่แสดงด้านล่าง
package com.example.MyFirstApplication.components;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.BeginRender;
public class Hello {
@BeginRender
void renderMessage(MarkupWriter writer) {
writer.write("<p>Hello, Tapestry (from component)</p>");
}
}
ให้เราเปลี่ยนเทมเพลตคอมโพเนนต์และรวมองค์ประกอบ <body /> ตามที่แสดงในบล็อกโค้ดด้านล่าง
<html>
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div>
<t:body />
</div>
</html>
ตอนนี้เทมเพลตของเพจอาจรวมเนื้อหาในมาร์กอัปส่วนประกอบดังที่แสดงด้านล่าง
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:hello>
<p>Hello, Tapestry (from page).</p>
</t:hello>
</html>
ผลลัพธ์จะเป็นดังนี้ -
<html>
<div>
<p>Hello, Tapestry (from page).</p>
</div>
</html>
พารามิเตอร์
วัตถุประสงค์หลักของพารามิเตอร์เหล่านี้คือการสร้างการเชื่อมต่อระหว่างฟิลด์ของคอมโพเนนต์และคุณสมบัติ / ทรัพยากรของเพจ การใช้พารามิเตอร์ส่วนประกอบและหน้าที่เกี่ยวข้องสื่อสารและถ่ายโอนข้อมูลระหว่างกัน นี้เรียกว่าTwo Way Data Binding.
ตัวอย่างเช่นคอมโพเนนต์กล่องข้อความที่ใช้แทนอายุในเพจการจัดการผู้ใช้จะได้รับค่าเริ่มต้น (พร้อมใช้งานในฐานข้อมูล) ผ่านพารามิเตอร์ อีกครั้งหลังจากอัปเดตและส่งอายุของผู้ใช้แล้วคอมโพเนนต์จะส่งอายุที่อัปเดตกลับมาผ่านพารามิเตอร์เดียวกัน
ในการสร้างพารามิเตอร์ใหม่ในคลาสคอมโพเนนต์ให้ประกาศฟิลด์และระบุ a @Parameterคำอธิบายประกอบ @Parameter นี้มีอาร์กิวเมนต์ที่เป็นทางเลือกสองแบบซึ่ง ได้แก่ -
required- ทำให้พารามิเตอร์เป็นสิ่งจำเป็น Tapestry มีข้อยกเว้นหากไม่มีให้
value - ระบุค่าเริ่มต้นของพารามิเตอร์
ควรระบุพารามิเตอร์ในเทมเพลตเพจเป็นแอตทริบิวต์ของแท็กคอมโพเนนต์ ควรระบุค่าของแอตทริบิวต์โดยใช้ Binding Expression / Expansion ซึ่งเราได้พูดถึงในบทก่อนหน้านี้ ส่วนขยายบางส่วนที่เราได้เรียนรู้ก่อนหน้านี้ ได้แก่ -
Property expansion (prop:«val») - รับข้อมูลจากคุณสมบัติของคลาสเพจ
Message expansion (message:«val») - รับข้อมูลจากคีย์ที่กำหนดในไฟล์ index.properties
Context expansion (context:«val») - รับข้อมูลจากโฟลเดอร์บริบทเว็บ / src / main / webapp
Asset expansion (asset:«val») - รับข้อมูลจากทรัพยากรที่ฝังอยู่ในไฟล์ jar / META-INF / assets
Symbol expansion (symbol:«val») - รับข้อมูลจากสัญลักษณ์ที่กำหนดใน AppModule.javafile
Tapestry มีส่วนขยายที่มีประโยชน์มากมายซึ่งบางส่วนได้รับด้านล่าง -
Literal expansion (literal:«val») - สตริงตามตัวอักษร
Var expansion (var:«val») - อนุญาตให้อ่านหรืออัปเดตตัวแปรการแสดงผลขององค์ประกอบ
Validate expansion (validate:«val»)- สตริงพิเศษที่ใช้เพื่อระบุกฎการตรวจสอบของออบเจ็กต์ ตัวอย่างเช่น validate: required, minLength = 5
Translate (translate:«val») - ใช้เพื่อระบุคลาส Translator (การแปลงฝั่งไคลเอ็นต์เป็นการแสดงฝั่งเซิร์ฟเวอร์) ในการตรวจสอบอินพุต
Block (block:«val») - รหัสขององค์ประกอบบล็อกภายในเทมเพลต
Component (component:«val») - รหัสของส่วนประกอบอื่นภายในเทมเพลต
การขยายทั้งหมดข้างต้นเป็นแบบอ่านอย่างเดียวยกเว้นการขยายคุณสมบัติและการขยาย Var ส่วนประกอบเหล่านี้ใช้เพื่อแลกเปลี่ยนข้อมูลกับเพจ เมื่อใช้การขยายเป็นค่าแอตทริบิวต์${...}ไม่ควรใช้ แทนที่จะใช้การขยายตัวโดยไม่มีสัญลักษณ์ดอลลาร์และวงเล็บปีกกา
ส่วนประกอบโดยใช้พารามิเตอร์
ให้เราสร้างคอมโพเนนต์ใหม่ HelloWithParameter โดยการปรับเปลี่ยนคอมโพเนนต์ Hello เพื่อแสดงข้อความแบบไดนามิกโดยการเพิ่ม name พารามิเตอร์ในคลาสคอมโพเนนต์และเปลี่ยนเทมเพลตคอมโพเนนต์และเทมเพลตเพจตามนั้น
สร้างคลาสส่วนประกอบใหม่ HelloWithParameter.java.
เพิ่มเขตข้อมูลส่วนตัวและตั้งชื่อด้วย @Parameterคำอธิบายประกอบ ใช้อาร์กิวเมนต์ที่จำเป็นเพื่อทำให้เป็นข้อบังคับ
@Parameter(required = true)
private String name;
เพิ่มฟิลด์ส่วนตัวผลลัพธ์ด้วย @Properyคำอธิบายประกอบ คุณสมบัติผลลัพธ์จะถูกใช้ในเทมเพลตคอมโพเนนต์ เทมเพลตคอมโพเนนต์ไม่มีสิทธิ์เข้าถึงฟิลด์ที่มีคำอธิบายประกอบ@Parameter และสามารถเข้าถึงได้เฉพาะฟิลด์ที่มีคำอธิบายประกอบ @Property. ตัวแปรที่มีอยู่ในเทมเพลตคอมโพเนนต์เรียกว่า Render Variables
@Property
private String result;
เพิ่มเมธอด RenderBody และคัดลอกค่าจากพารามิเตอร์ name ไปยังคุณสมบัติผลลัพธ์
@BeginRender
void initializeValues() {
result = name;
}
เพิ่มเทมเพลตองค์ประกอบใหม่ HelloWithParamter.tml และใช้คุณสมบัติผลลัพธ์เพื่อแสดงข้อความ
<div> Hello, ${result} </div>
เพิ่มคุณสมบัติใหม่ชื่อผู้ใช้ในหน้าทดสอบ (testhello.java)
public String getUsername() {
return "User1";
}
ใช้คอมโพเนนต์ที่สร้างขึ้นใหม่ในเทมเพลตเพจและตั้งค่าคุณสมบัติชื่อผู้ใช้ในชื่อพารามิเตอร์ของ HelloWithParameter ส่วนประกอบ.
<t:helloWithParameter name = "username" />
รายชื่อที่สมบูรณ์มีดังนี้ -
package com.example.MyFirstApplication.components;
import org.apache.tapestry5.annotations.*;
public class HelloWithParameter {
@Parameter(required = true)
private String name;
@Property
private String result;
@BeginRender
void initializeValues() {
result = name;
}
}
<html
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div> Hello, ${result} </div>
</html>
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.*;
public class TestHello {
public String getUsername() {
return "User1";
}
}
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:helloWithParameter name = "username" />
</html>
ผลลัพธ์จะเป็นดังนี้ -
<div> Hello, User1 </div>
พารามิเตอร์ขั้นสูง
ในบทก่อนหน้านี้เราได้วิเคราะห์วิธีสร้างและใช้พารามิเตอร์ง่ายๆในคอมโพเนนต์ที่กำหนดเอง พารามิเตอร์ขั้นสูงอาจมีมาร์กอัปที่สมบูรณ์เช่นกัน ในกรณีนี้ควรระบุมาร์กอัปภายในแท็กส่วนประกอบเช่นส่วนย่อยในเทมเพลตเพจ องค์ประกอบ if ในตัวมีมาร์กอัปสำหรับทั้งความสำเร็จและเงื่อนไขความล้มเหลว มาร์กอัปสำหรับความสำเร็จถูกระบุเป็นเนื้อหาของแท็กส่วนประกอบและระบุมาร์กอัปของความล้มเหลวโดยใช้ไฟล์elseparameter.
ให้เราดูวิธีการใช้ ifส่วนประกอบ. องค์ประกอบ if มีสองพารามิเตอร์ -
test - พารามิเตอร์ตามคุณสมบัติอย่างง่าย
Else - พารามิเตอร์ขั้นสูงใช้เพื่อระบุมาร์กอัปทางเลือกหากเงื่อนไขล้มเหลว
Tapestry จะตรวจสอบค่าของคุณสมบัติการทดสอบโดยใช้ตรรกะต่อไปนี้และส่งคืนจริงหรือเท็จ นี้เรียกว่าType Coercionวิธีแปลงวัตถุประเภทหนึ่งไปเป็นอีกประเภทหนึ่งที่มีเนื้อหาเดียวกัน
ถ้าชนิดข้อมูลเป็น String,“ True” ถ้าไม่เว้นว่างและไม่ใช่สตริงตามตัวอักษร“ False” (ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่)
ถ้าชนิดข้อมูลเป็น Numberจริงถ้าไม่ใช่ศูนย์
ถ้าชนิดข้อมูลเป็น Collectionจริงถ้าไม่ว่างเปล่า
ถ้าชนิดข้อมูลเป็น Object, จริง (ตราบใดที่ไม่เป็นโมฆะ)
หากเงื่อนไขผ่านไปส่วนประกอบจะแสดงผลร่างกาย มิฉะนั้นจะแสดงเนื้อหาของพารามิเตอร์ else
รายชื่อที่สมบูรณ์มีดังนี้ -
package com.example.MyFirstApplication.pages;
public class TestIf {
public String getUser() {
return "User1";
}
}
<html title = "If Test Page"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<body>
<h1>Welcome!</h1>
<t:if test = "user">
Welcome back, ${user}
<p:else>
Please <t:pagelink page = "login">Login</t:pagelink>
</p:else>
</t:if>
</body>
</html>
เหตุการณ์คอมโพเนนต์ / การนำทางเพจ
แอปพลิเคชั่น Tapestry คือไฟล์ collection of Pagesมีปฏิสัมพันธ์ซึ่งกันและกัน จนถึงตอนนี้เราได้เรียนรู้วิธีสร้างเพจแต่ละเพจโดยไม่มีการสื่อสารระหว่างกัน วัตถุประสงค์หลักของเหตุการณ์คอมโพเนนต์คือการจัดเตรียมการโต้ตอบระหว่างเพจ (ภายในเพจด้วย) โดยใช้เหตุการณ์ฝั่งเซิร์ฟเวอร์ เหตุการณ์คอมโพเนนต์ส่วนใหญ่เกิดจากเหตุการณ์ฝั่งไคลเอ็นต์
ตัวอย่างเช่นเมื่อผู้ใช้คลิกลิงก์ในเพจ Tapestry จะเรียกเพจเดียวกันด้วยข้อมูลเป้าหมายแทนที่จะเรียกเพจเป้าหมายและเพิ่มเหตุการณ์ที่ฝั่งเซิร์ฟเวอร์ เพจ Tapestry จะบันทึกเหตุการณ์ประมวลผลข้อมูลเป้าหมายและทำการเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์ไปยังเพจเป้าหมาย
Tapestry ตามด้วย Post/Redirect/Get (RPG) design patternสำหรับการนำทางหน้า ใน RPG เมื่อผู้ใช้ส่งคำขอโพสต์โดยส่งแบบฟอร์มเซิร์ฟเวอร์จะประมวลผลข้อมูลที่โพสต์ แต่จะไม่ส่งคืนการตอบกลับโดยตรง แต่จะทำการเปลี่ยนเส้นทางฝั่งไคลเอ็นต์ไปยังเพจอื่นแทนซึ่งจะแสดงผลลัพธ์ รูปแบบ RPG ใช้เพื่อป้องกันการส่งแบบฟอร์มซ้ำผ่านปุ่มย้อนกลับของเบราว์เซอร์ปุ่มรีเฟรชเบราว์เซอร์ ฯลฯ Tapestry จัดเตรียมรูปแบบ RPG โดยให้คำขอสองประเภทต่อไปนี้
Component Event Request- คำขอประเภทนี้กำหนดเป้าหมายไปที่องค์ประกอบเฉพาะในเพจและเพิ่มเหตุการณ์ภายในคอมโพเนนต์ คำขอนี้ทำการเปลี่ยนเส้นทางเท่านั้นและไม่ส่งออกการตอบสนอง
Render Request - คำขอประเภทนี้กำหนดเป้าหมายเพจและสตรีมการตอบกลับไปยังไคลเอนต์
เพื่อให้เข้าใจเหตุการณ์ของคอมโพเนนต์และการนำทางของหน้าเราจำเป็นต้องทราบรูปแบบ URL ของคำขอ tapestry รูปแบบ URL สำหรับคำขอทั้งสองประเภทมีดังนี้ -
Component Event Requests -
/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
Render Request -
/<<page_name_with_path>>/<<context_information>>
ตัวอย่างบางส่วนของรูปแบบ URL ได้แก่ -
สามารถขอหน้าดัชนีได้โดย https://«domain»/«app»/index.
หากหน้าดัชนีอยู่ภายใต้ผู้ดูแลระบบโฟลเดอร์ย่อยสามารถร้องขอได้โดย https://«domain»/«app»/admin/index.
หากผู้ใช้คลิกที่ไฟล์ ActionLink component ด้วย id test ในหน้าดัชนีจากนั้น URL จะเป็น https://«domain»/«app»/index.test.
เหตุการณ์
โดยค่าเริ่มต้น Tapestry จะเพิ่มขึ้น OnPassivate และ OnActivateกิจกรรมสำหรับคำขอทั้งหมด สำหรับประเภทการร้องขอเหตุการณ์คอมโพเนนต์ Tapestry จะเพิ่มเหตุการณ์อย่างน้อยหนึ่งเหตุการณ์ขึ้นอยู่กับส่วนประกอบ คอมโพเนนต์ ActionLink เพิ่มเหตุการณ์การดำเนินการในขณะที่คอมโพเนนต์ฟอร์มเพิ่มหลายเหตุการณ์เช่นValidate, Successฯลฯ
เหตุการณ์สามารถจัดการได้ในคลาสเพจโดยใช้ตัวจัดการเมธอดที่เกี่ยวข้อง ตัวจัดการเมธอดถูกสร้างขึ้นโดยใช้หลักการตั้งชื่อเมธอดหรือผ่านไฟล์@OnEventคำอธิบายประกอบ รูปแบบของหลักการตั้งชื่อวิธีคือOn«EventName»From«ComponentId».
เหตุการณ์การดำเนินการของคอมโพเนนต์ ActionLink กับ id test สามารถจัดการได้ด้วยวิธีใดวิธีหนึ่งดังต่อไปนี้ -
void OnActionFromTest() {
}
@OnEvent(component = "test", name = "action")
void CustomFunctionName() {
}
หากชื่อเมธอดไม่มีองค์ประกอบเฉพาะใด ๆ เมธอดนั้นจะถูกเรียกใช้สำหรับองค์ประกอบทั้งหมดที่มีเหตุการณ์ที่ตรงกัน
void OnAction() {
}
OnPassivate และ OnActivate Event
OnPassivate ใช้เพื่อจัดเตรียมข้อมูลบริบทสำหรับตัวจัดการเหตุการณ์ OnActivate โดยทั่วไป Tapestry จะให้ข้อมูลบริบทและสามารถใช้เป็นอาร์กิวเมนต์ในตัวจัดการ OnActivateevent
ตัวอย่างเช่นหากข้อมูลบริบทเป็น 3 ประเภท int ดังนั้นเหตุการณ์ OnActivate สามารถเรียกเป็น -
void OnActivate(int id) {
}
ในบางสถานการณ์อาจไม่มีข้อมูลบริบท ในสถานการณ์นี้เราสามารถจัดเตรียมข้อมูลบริบทให้กับตัวจัดการเหตุการณ์ OnActivate ผ่านตัวจัดการเหตุการณ์ OnPassivate ชนิดการส่งคืนของตัวจัดการเหตุการณ์ OnPassivate ควรใช้เป็นอาร์กิวเมนต์ของตัวจัดการเหตุการณ์ OnActivate
int OnPassivate() {
int id = 3;
return id;
}
void OnActivate(int id) {
}
ค่าส่งคืนตัวจัดการเหตุการณ์
Tapestry ปัญหาการเปลี่ยนเส้นทางหน้าตามค่าที่ส่งคืนของตัวจัดการเหตุการณ์ ตัวจัดการเหตุการณ์ควรส่งคืนค่าใดค่าหนึ่งต่อไปนี้
Null Response- ส่งคืนค่าว่าง Tapestry จะสร้าง URL ของหน้าปัจจุบันและส่งไปยังไคลเอนต์เป็นการเปลี่ยนเส้นทาง
public Object onAction() {
return null;
}
String Response- ส่งกลับค่าสตริง Tapestry จะสร้าง URL ของหน้าที่ตรงกับค่าและส่งไปยังไคลเอนต์เป็นการเปลี่ยนเส้นทาง
public String onAction() {
return "Index";
}
Class Response- ส่งคืนคลาสเพจ Tapestry จะสร้าง URL ของคลาสหน้าที่ส่งคืนและส่งไปยังไคลเอนต์เป็นการเปลี่ยนเส้นทาง
public Object onAction() {
return Index.class
}
Page Response- ส่งคืนฟิลด์ที่มีคำอธิบายประกอบด้วย @InjectPage Tapestry จะสร้าง URL ของหน้าที่แทรกและส่งไปยังไคลเอนต์เป็นการเปลี่ยนเส้นทาง
@InjectPage
private Index index;
public Object onAction(){
return index;
}
HttpError- ส่งคืนวัตถุ HTTPError Tapestry จะแสดงข้อผิดพลาด HTTP ฝั่งไคลเอ็นต์
public Object onAction(){
return new HttpError(302, "The Error message);
}
Link Response- ส่งคืนอินสแตนซ์ลิงก์โดยตรง Tapestry จะสร้าง URL จากออบเจ็กต์ Link และส่งไปยังไคลเอนต์เป็นการเปลี่ยนเส้นทาง
Stream Response - ส่งคืนไฟล์ StreamResponseวัตถุ. Tapestry จะส่งสตรีมเป็นการตอบสนองโดยตรงไปยังเบราว์เซอร์ไคลเอนต์ ใช้เพื่อสร้างรายงานและรูปภาพโดยตรงและส่งไปยังไคลเอนต์
Url Response - ส่งคืนไฟล์ java.net.URLวัตถุ. Tapestry จะได้รับ URL ที่สอดคล้องกันจากออบเจ็กต์และส่งไปยังไคลเอนต์เป็นการเปลี่ยนเส้นทาง
Object Response- ส่งคืนค่าใด ๆ นอกเหนือจากค่าที่ระบุไว้ข้างต้น Tapestry จะทำให้เกิดข้อผิดพลาด
บริบทเหตุการณ์
โดยทั่วไปตัวจัดการเหตุการณ์สามารถรับข้อมูลบริบทโดยใช้อาร์กิวเมนต์ ตัวอย่างเช่นหากข้อมูลบริบทเป็น 3 ประเภท int ตัวจัดการเหตุการณ์จะเป็น -
Object onActionFromTest(int id) {
}
Tapestry จัดการข้อมูลบริบทอย่างเหมาะสมและจัดเตรียมวิธีการผ่านอาร์กิวเมนต์ บางครั้ง Tapestry อาจไม่สามารถจัดการได้อย่างถูกต้องเนื่องจากความซับซ้อนของการเขียนโปรแกรม เมื่อถึงเวลานั้นเราอาจได้รับข้อมูลบริบทที่สมบูรณ์และดำเนินการเอง
Object onActionFromEdit(EventContext context) {
if (context.getCount() > 0) {
this.selectedId = context.get(0);
} else {
alertManager.warn("Please select a document.");
return null;
}
}
บทนี้จะอธิบายเกี่ยวกับส่วนประกอบในตัวที่ Tapestry มีพร้อมตัวอย่างที่เหมาะสม Tapestry รองรับส่วนประกอบในตัวมากกว่า 65 ชิ้น คุณยังสามารถสร้างส่วนประกอบแบบกำหนดเอง ให้เราอธิบายรายละเอียดส่วนประกอบที่โดดเด่นบางส่วน
ถ้า Component
องค์ประกอบ if ถูกใช้เพื่อแสดงผลบล็อกตามเงื่อนไข เงื่อนไขถูกตรวจสอบโดยพารามิเตอร์ทดสอบ
สร้างเพจ IfSample.java ดังแสดงด้านล่าง -
package com.example.MyFirstApplication.pages;
public class Ifsample {
public String getUser() {
return "user1";
}
}
ตอนนี้สร้างไฟล์เทมเพลตที่เกี่ยวข้องดังนี้ -
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3>If-else component example </h3>
<t:if test = "user">
Hello ${user}
<p:else>
<h4> You are not a Tapestry user </h4>
</p:else>
</t:if>
</html>
การร้องขอเพจจะแสดงผลดังภาพด้านล่าง
Result - http: // localhost: 8080 / MyFirstApplication / ifsample
ยกเว้นและตัวแทนตัวแทน
unless componentเป็นเพียงสิ่งที่ตรงกันข้ามกับองค์ประกอบ if ที่กล่าวไว้ข้างต้น ในขณะที่delegate componentไม่ได้ทำการเรนเดอร์ด้วยตัวเอง โดยปกติจะมอบหมายมาร์กอัปเพื่อบล็อกองค์ประกอบ เว้นแต่และถ้าคอมโพเนนต์สามารถใช้ delegate และ block เพื่อสลับเนื้อหาไดนามิกตามเงื่อนไข
สร้างเพจ Unless.java ดังต่อไปนี้.
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;
public class Unless {
@Property
@Persist(PersistenceConstants.FLASH)
private String value;
@Property
private Boolean bool;
@Inject
Block t, f, n;
public Block getCase() {
if (bool == Boolean.TRUE ) {
return t;
} else {
return f;
}
}
}
ตอนนี้สร้างไฟล์เทมเพลตที่เกี่ยวข้องดังนี้ -
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h4> Delegate component </h4>
<div class = "div1">
<t:delegate to = "case"/>
</div>
<h4> If-Unless component </h4>
<div class = "div1">
<t:if test = "bool">
<t:delegate to = "block:t"/>
</t:if>
<t:unless test = "bool">
<t:delegate to = "block:notT"/>
</t:unless>
</div>
<t:block id = "t">
bool == Boolean.TRUE.
</t:block>
<t:block id = "notT">
bool = Boolean.FALSE.
</t:block>
<t:block id = "f">
bool == Boolean.FALSE.
</t:block>
</html>
การร้องขอเพจจะแสดงผลดังภาพด้านล่าง
Result - http: // localhost: 8080 / MyFirstApplication / เว้นแต่
ห่วงส่วนประกอบ
ส่วนประกอบลูปเป็นส่วนประกอบพื้นฐานในการวนซ้ำรายการคอลเลกชันและแสดงผลเนื้อหาสำหรับทุกค่า / การวนซ้ำ
สร้างหน้า Loop ตามที่แสดงด้านล่าง -
Loop.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class Loop {
@Property
private int i;
}
จากนั้นสร้างเทมเพลตที่เกี่ยวข้อง Loop.tml
Loop.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<p>This is sample parameter rendering example...</p>
<ol>
<li t:type = "loop" source = "1..5" value = "var:i">${var:i}</li>
</ol>
</html>
ส่วนประกอบลูปมีพารามิเตอร์สองตัวต่อไปนี้ -
source- แหล่งรวบรวม. 1 … 5 เป็นส่วนขยายคุณสมบัติที่ใช้ในการสร้างอาร์เรย์ที่มีช่วงที่ระบุ
var- ตัวแปร Render ใช้เพื่อแสดงค่าปัจจุบันในเนื้อหาของเทมเพลต
การร้องขอหน้าเว็บจะแสดงผลลัพธ์ดังที่แสดงด้านล่าง -
ส่วนประกอบ PageLink
คอมโพเนนต์ PageLink ใช้เพื่อเชื่อมโยงเพจจากเพจหนึ่งไปยังเพจอื่น สร้างหน้าทดสอบ PageLink ตามด้านล่าง -PageLink.java.
package com.example.MyFirstApplication.pages;
public class PageLink {
}
จากนั้นสร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง -
PageLink.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<body>
<h3><u>Page Link</u> </h3>
<div class = "page">
<t:pagelink page = "Index">Click here to navigate Index page</t:pagelink>
<br/>
</div>
</body>
</html>
คอมโพเนนต์ PageLink มีพารามิเตอร์เพจซึ่งควรอ้างถึงเพจ Tapestry เป้าหมาย
Result - http: // localhost: 8080 / myFirstApplication / pagelink
คอมโพเนนต์ EventLink
คอมโพเนนต์ EventLink ส่งชื่อเหตุการณ์และพารามิเตอร์ที่เกี่ยวข้องผ่าน URL สร้างคลาสเพจ EventsLink ตามที่แสดงด้านล่าง
EventsLink.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class EventsLink {
@Property
private int x;
void onActivate(int count) {
this.x = x;
}
int onPassivate() {
return x;
}
void onAdd(int value) {
x += value;
}
}
จากนั้นสร้างไฟล์เทมเพลต“ EventsLink” ที่เกี่ยวข้องดังต่อไปนี้ -
EventsLink.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3> Event link example </h3>
AddedCount = ${x}. <br/>
<t:eventlink t:event = "add" t:context = "literal:1">
Click here to add count
</t:eventlink><br/>
</html>
EventLink มีสองพารามิเตอร์ต่อไปนี้ -
Event- ชื่อของเหตุการณ์ที่จะทริกเกอร์ในคอมโพเนนต์ EventLink โดยค่าเริ่มต้นจะชี้ไปที่ id ของส่วนประกอบ
Context- เป็นพารามิเตอร์เสริม เป็นการกำหนดบริบทสำหรับลิงก์
Result - http: // localhost: 8080 / myFirstApplication / EventsLink
หลังจากคลิกค่านับหน้าจะแสดงชื่อเหตุการณ์ใน URL ดังที่แสดงในภาพหน้าจอผลลัพธ์ต่อไปนี้
ส่วนประกอบ ActionLink
คอมโพเนนต์ ActionLink คล้ายกับคอมโพเนนต์ EventLink แต่จะส่งเฉพาะรหัสส่วนประกอบเป้าหมาย ชื่อเหตุการณ์เริ่มต้นคือการกระทำ
สร้างเพจ“ ActivationLinks.java” ดังที่แสดงด้านล่าง
ActivationLinks.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class ActivationLinks {
@Property
private int x;
void onActivate(int count) {
this.x = x;
}
int onPassivate() {
return x;
}
void onActionFromsub(int value) {
x -= value;
}
}
ตอนนี้สร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง -
ActivationLinks.tml
<html t:type = "Newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div class = "div1">
Count = ${count}. <br/>
<t:actionlink t:id = "sub" t:context = "literal:1">
Decrement
</t:actionlink><br/>
</div>
</html>
ที่นี่ OnActionFromSub เมธอดจะถูกเรียกเมื่อคลิกคอมโพเนนต์ ActionLink
Result - http: // localhost: 8080 / myFirstApplication / ActivationsLink
ส่วนประกอบการแจ้งเตือน
กล่องโต้ตอบการแจ้งเตือนส่วนใหญ่จะใช้เพื่อส่งข้อความเตือนไปยังผู้ใช้ ตัวอย่างเช่นหากช่องป้อนข้อมูลต้องการข้อความที่จำเป็น แต่ผู้ใช้ไม่ได้ป้อนข้อมูลใด ๆ จากนั้นในฐานะส่วนหนึ่งของการตรวจสอบความถูกต้องคุณสามารถใช้กล่องแจ้งเตือนเพื่อส่งข้อความเตือนได้
สร้างเพจ“ การแจ้งเตือน” ตามที่แสดงในโปรแกรมต่อไปนี้
Alerts.java
package com.example.MyFirstApplication.pages;
public class Alerts {
public String getUser() {
return "user1";
}
}
จากนั้นสร้างไฟล์เทมเพลตที่เกี่ยวข้องดังต่อไปนี้ -
Alerts.tml
<html t:type = "Newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3>Alerts</h3>
<div class = "alert alert-info">
<h5> Welcome ${user} </h5>
</div>
</html>
การแจ้งเตือนมีระดับความรุนแรงสามระดับ ได้แก่ -
- Info
- Warn
- Error
เทมเพลตด้านบนสร้างขึ้นโดยใช้การแจ้งเตือนข้อมูล ถูกกำหนดให้เป็นalert-info. คุณสามารถสร้างความรุนแรงอื่น ๆ ขึ้นอยู่กับความต้องการ
การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/Alerts
Form Componentใช้เพื่อสร้างแบบฟอร์มในหน้า Tapestry สำหรับการป้อนข้อมูลของผู้ใช้ แบบฟอร์มสามารถมีฟิลด์ข้อความฟิลด์วันที่ช่องทำเครื่องหมายเลือกตัวเลือกปุ่มส่งและอื่น ๆ
บทนี้จะอธิบายรายละเอียดเกี่ยวกับส่วนประกอบฟอร์มเด่นบางส่วน
องค์ประกอบช่องทำเครื่องหมาย
คอมโพเนนต์ช่องทำเครื่องหมายถูกใช้เพื่อเลือกระหว่างสองตัวเลือกที่ใช้ร่วมกันโดยเฉพาะ สร้างเพจโดยใช้ Checkbox ตามที่แสดงด้านล่าง -
Checkbox.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
public class Checkbox {
@Property
private boolean check1;
@Property
private boolean check2;
}
ตอนนี้สร้างเทมเพลตที่เกี่ยวข้อง Checkbox.tml ดังแสดงด้านล่าง -
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3> checkbox component</h3>
<t:form>
<t:checkbox t:id = "check1"/> I have a bike <br/>
<t:checkbox t:id = "check2"/> I have a car
</t:form>
</html>
ที่นี่รหัสพารามิเตอร์ช่องทำเครื่องหมายตรงกับค่าบูลีนที่เกี่ยวข้อง
Result - หลังจากขอเพจแล้วช่อง http: // localhost: 8080 / myFirstApplication / จะให้ผลลัพธ์ดังต่อไปนี้
ส่วนประกอบ TextField
ส่วนประกอบ TextField ช่วยให้ผู้ใช้สามารถแก้ไขข้อความบรรทัดเดียวได้ สร้างเพจText ดังแสดงด้านล่าง
Text.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.TextField;public class Text {
@Property
private String fname;
@Property
private String lname;
}
จากนั้นสร้างเทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง - Text.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<p> Form application </p>
<body>
<h3> Text field created from Tapestry component </h3>
<t:form>
<table>
<tr>
<td>
Firstname: </td> <td><t:textfield t:id = "fname" />
</td>
<td>Lastname: </td> <td> <t:textfield t:id = "lname" /> </td>
</tr>
</table>
</t:form>
</body>
</html>
ที่นี่หน้าข้อความมีคุณสมบัติชื่อ fname และ lname. คุณสมบัตินี้เข้าถึงรหัสส่วนประกอบ
การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/Text
ส่วนประกอบ PasswordField
PasswordField เป็นช่องข้อความเฉพาะสำหรับรหัสผ่าน สร้างรหัสผ่านของเพจตามที่แสดงด้านล่าง -
Password.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.PasswordField;
public class Password {
@Property
private String pwd;
}
ตอนนี้สร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง -
Password.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<p> Form application </p>
<h3> Password field created from Tapestry component </h3>
<t:form>
<table>
<tr>
<td> Password: </td>
<td><t:passwordfield t:id = "pwd"/> </td>
</tr>
</table>
</t:form>
</html>
ที่นี่คอมโพเนนต์ PasswordField มีรหัสพารามิเตอร์ซึ่งชี้ไปที่คุณสมบัติ pwd. การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/Password
ส่วนประกอบ TextArea
ส่วนประกอบ TextArea คือตัวควบคุมข้อความอินพุตหลายบรรทัด สร้างเพจ TxtArea ดังภาพด้านล่าง
TxtArea.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.TextArea;
public class TxtArea {
@Property
private String str;
}
จากนั้นสร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง
TxtArea.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3>TextArea component </h3>
<t:form>
<table>
<tr>
<td><t:textarea t:id = "str"/>
</td>
</tr>
</table>
</t:form>
</html>
ที่นี่รหัสพารามิเตอร์คอมโพเนนต์ TextArea ชี้ไปที่คุณสมบัติ“ str” การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/TxtArea**
เลือกส่วนประกอบ
ส่วนประกอบ Select มีรายการตัวเลือกแบบหล่นลง สร้างเพจ SelectOption ดังภาพด้านล่าง
SelectOption.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Select;
public class SelectOption {
@Property
private String color0;
@Property
private Color1 color1;
public enum Color1 {
YELLOW, RED, GREEN, BLUE, ORANGE
}
}
จากนั้นสร้างเทมเพลตที่สอดคล้องกันดังนี้ -
SelectOption.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<p> Form application </p>
<h3> select component </h3>
<t:form>
<table>
<tr>
<td> Select your color here: </td>
<td> <select t:type = "select" t:id = "color1"></select></td>
</tr>
</table>
</t:form>
</html>
ที่นี่ส่วนประกอบ Select มีสองพารามิเตอร์ -
Type - ประเภทของคุณสมบัติคือ enum
Id - Id ชี้ไปที่คุณสมบัติ Tapestry“ color1”
การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/SelectOption
ส่วนประกอบของ RadioGroup
คอมโพเนนต์ RadioGroup จัดเตรียมกลุ่มคอนเทนเนอร์สำหรับส่วนประกอบวิทยุ คอมโพเนนต์ Radio และ RadioGroup ทำงานร่วมกันเพื่ออัพเดตคุณสมบัติของอ็อบเจ็กต์ ส่วนประกอบนี้ควรล้อมรอบส่วนประกอบวิทยุอื่น ๆ สร้างเพจใหม่“ Radiobutton.java” ดังแสดงด้านล่าง -
Radiobutton.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
public class Radiobutton {
@Property
@Persist(PersistenceConstants.FLASH)
private String value;
}
จากนั้นสร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง -
Radiobutton.tml
<html t:type = "Newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3>RadioGroup component </h3>
<t:form>
<t:radiogroup t:id = "value">
<t:radio t:id = "radioT" value = "literal:T" label = "Male" />
<t:label for = "radioT"/>
<t:radio t:id = "radioF" value = "literal:F" label = "Female"/>
<t:label for = "radioF"/>
</t:radiogroup>
</t:form>
</html>
ที่นี่รหัสคอมโพเนนต์ RadioGroup เชื่อมโยงกับคุณสมบัติ "value" การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้
http://localhost:8080/myFirstApplication/Radiobutton
ส่งส่วนประกอบ
เมื่อผู้ใช้คลิกปุ่มส่งแบบฟอร์มจะถูกส่งไปยังที่อยู่ที่ระบุไว้ในการตั้งค่าการดำเนินการของแท็ก สร้างเพจSubmitComponent ดังแสดงด้านล่าง
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.InjectPage;
public class SubmitComponent {
@InjectPage
private Index page1;
Object onSuccess() {
return page1;
}
}
ตอนนี้สร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง
SubmitComponent.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h3>Tapestry Submit component </h3>
<body>
<t:form>
<t:submit t:id = "submit1" value = "Click to go Index"/>
</t:form>
</body>
</html>
ที่นี่องค์ประกอบ Submit จะส่งค่าไปยังหน้าดัชนี การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/SubmitComponent
การตรวจสอบแบบฟอร์ม
โดยปกติการตรวจสอบแบบฟอร์มจะเกิดขึ้นที่เซิร์ฟเวอร์หลังจากไคลเอนต์ป้อนข้อมูลที่จำเป็นทั้งหมดแล้วจึงส่งแบบ หากข้อมูลที่ไคลเอนต์ป้อนไม่ถูกต้องหรือขาดหายไปเซิร์ฟเวอร์จะต้องส่งข้อมูลทั้งหมดกลับไปยังไคลเอนต์และขอให้ส่งแบบฟอร์มอีกครั้งพร้อมข้อมูลที่ถูกต้อง
ให้เราพิจารณาตัวอย่างง่ายๆต่อไปนี้เพื่อทำความเข้าใจกระบวนการตรวจสอบความถูกต้อง
สร้างเพจ Validate ดังแสดงด้านล่าง
Validate.java
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;
public class Validate {
@Property
@Persist(PersistenceConstants.FLASH)
private String firstName;
@Property
@Persist(PersistenceConstants.FLASH)
private String lastName;
}
ตอนนี้สร้างไฟล์เทมเพลตที่เกี่ยวข้องดังที่แสดงด้านล่าง
Validate.tml
<html t:type = "newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:form>
<table>
<tr>
<td><t:label for = "firstName"/>:</td>
<td><input t:type = "TextField" t:id = "firstName"
t:validate = "required, maxlength = 7" size = "10"/></td>
</tr>
<tr>
<td><t:label for = "lastName"/>:</td>
<td><input t:type = "TextField" t:id = "lastName"
t:validate = "required, maxLength = 5" size = "10"/></td>
</tr>
</table>
<t:submit t:id = "sub" value =" Form validation"/>
</t:form>
</html>
Form Validation มีพารามิเตอร์ที่สำคัญดังต่อไปนี้ -
Max - กำหนดค่าสูงสุดเช่น = «ค่าสูงสุด 20 »
MaxDate- กำหนด maxDate เช่น = «วันที่สูงสุด 06/09/2556 » ในทำนองเดียวกันคุณสามารถกำหนด MinDate ได้เช่นกัน
MaxLength - maxLength สำหรับเช่น = «ความยาวสูงสุด 80 »
Min - ขั้นต่ำ
MinLength - ความยาวขั้นต่ำสำหรับเช่น = «ความยาวขั้นต่ำ 2 »
Email - การตรวจสอบอีเมลซึ่งใช้อีเมลมาตรฐาน regexp ^ \ w [._ \ w] * \ w @ \ w [-._ \ w] * \ w \. \ w2,6 $ หรือไม่มีเลย
การร้องขอเพจจะให้ผลลัพธ์ดังต่อไปนี้ -
http://localhost:8080/myFirstApplication/Validate
AJAX ย่อมาจาก Asynchronous JavaScript and XML. เป็นเทคนิคในการสร้างเว็บแอปพลิเคชันที่ดีขึ้นเร็วขึ้นและโต้ตอบได้มากขึ้นด้วยความช่วยเหลือของXML, JSON, HTML, CSS, และ JavaScript. AJAX ช่วยให้คุณสามารถส่งและรับข้อมูลแบบอะซิงโครนัสโดยไม่ต้องโหลดหน้าเว็บซ้ำดังนั้นจึงเป็นไปอย่างรวดเร็ว
ส่วนประกอบโซน
ส่วนประกอบโซนถูกใช้เพื่อจัดเตรียมเนื้อหา (มาร์กอัป) รวมทั้งตำแหน่งของเนื้อหาเอง Tapestry จะใช้เนื้อความของ Zone Component ภายในเพื่อสร้างเนื้อหา เมื่อสร้างเนื้อหาไดนามิกแล้ว Tapestry จะส่งไปยังไคลเอนต์แสดงข้อมูลในตำแหน่งที่ถูกต้องทริกเกอร์และทำให้ HTML เคลื่อนไหวเพื่อดึงดูดความสนใจของผู้ใช้
คอมโพเนนต์โซนนี้ใช้ร่วมกับคอมโพเนนต์ EventLink EventLink มีตัวเลือกในการผูกกับโซนใดโซนหนึ่งโดยใช้ไฟล์t:zoneคุณลักษณะ. เมื่อกำหนดค่าโซนใน EventLink แล้วการคลิก EventLink จะเรียกการอัปเดตโซน นอกจากนี้เหตุการณ์ EventLink (refreshZone) สามารถใช้เพื่อควบคุมการสร้างข้อมูลไดนามิก
ตัวอย่างง่ายๆของ AJAX มีดังนี้ -
AjaxZone.tml
<html t:type = "Newlayout" title = "About MyFirstApplication"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<body>
<h1>Ajax time zone example</h1>
<div class = "div1">
<a t:type = "eventlink" t:event = "refreshZone" href = "#"
t:zone = "timeZone">Ajax Link </a><br/><br/>
<t:zone t:id = "timeZone" id = "timeZone">Time zone: ${serverTime}</t:zone>
</div>
</body>
</html>
AjaxZone.java
package com.example.MyFirstApplication.pages;
import java.util.Date;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Request;
public class AjaxZone {
@Inject
private Request request;
@InjectComponent
private Zone timeZone;
void onRefreshPage() {
}
Object onRefreshZone() {
return request.isXHR() ? timeZone.getBody() : null;
}
public Date getServerTime() {
return new Date();
}
}
ผลลัพธ์จะแสดงที่: http: // localhost: 8080 / MyFirstApplication / AjaxZone
ในบทนี้เราจะพูดถึงการรวม BeanEditForm และ Grid componentด้วยไฮเบอร์เนต Hibernate ถูกรวมเข้ากับ Tapestry ผ่านโมดูลไฮเบอร์เนต ในการเปิดใช้งานโมดูลไฮเบอร์เนตให้เพิ่มการพึ่งพา Tapestry-hibernate และเป็นทางเลือกhsqldb ใน pom.xmlไฟล์. ตอนนี้กำหนดค่าไฮเบอร์เนตผ่านไฟล์hibernate.cfg.xml ไฟล์ที่วางไว้ที่รากของโฟลเดอร์ทรัพยากร
pom.xml (บางส่วน)
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-hibernate</artifactId>
<version>${tapestry-release-version}</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
</dependency>
Hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name = "hibernate.connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name = "hibernate.connection.url">
jdbc:hsqldb:./target/work/sampleapp;shutdown = true
</property>
<property name = "hibernate.dialect">
org.hibernate.dialect.HSQLDialect
</property>
<property name = "hibernate.connection.username">sa</property>
<property name = "hibernate.connection.password"></property>
<property name = "hbm2ddl.auto">update</property>
<property name = "hibernate.show_sql">true</property>
<property name = "hibernate.format_sql">true</property>
</session-factory>
</hibernate-configuration>
ให้เราดูวิธีสร้างไฟล์ employee add page โดยใช้ส่วนประกอบ BeanEditForm และไฟล์ employee list pageโดยใช้องค์ประกอบกริด เลเยอร์ความคงอยู่ได้รับการจัดการโดยโมดูลไฮเบอร์เนต
สร้างคลาสพนักงานและตกแต่งด้วยคำอธิบายประกอบ @Entity จากนั้นเพิ่มคำอธิบายประกอบการตรวจสอบความถูกต้องสำหรับฟิลด์ที่เกี่ยวข้องและไฮเบอร์เนตคำอธิบายประกอบที่เกี่ยวข้อง @Id และ @GeneratedValue สำหรับฟิลด์ id นอกจากนี้ให้สร้างเพศเป็นประเภท enum
Employee.java
package com.example.MyFirstApplication.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.apache.tapestry5.beaneditor.NonVisual;
import org.apache.tapestry5.beaneditor.Validate;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NonVisual
public Long id;
@Validate("required")
public String firstName;
@Validate("required")
public String lastName;
@Validate("required")
public String userName;
@Validate("required")
public String password;
@Validate("required")
public String email;
public String phone;
@Validate("required")
public String Street;
@Validate("required")
public String city;
@Validate("required")
public String state;
@Validate("required,regexp=^\\d{5}(-\\d{4})?$")
public String zip;
}
Gender.java (enum)
package com.example.MyFirstApplication.data;
public enum Gender {
Male, Female
}
สร้างหน้ารายชื่อพนักงาน ListEmployee.java ในโฟลเดอร์ใหม่พนักงานภายใต้เพจและไฟล์เทมเพลตที่เกี่ยวข้อง ListEmployee.tml ที่ /src/main/resources/pages/employeeโฟลเดอร์ Tapestry จัดเตรียม URL แบบสั้นสำหรับโฟลเดอร์ย่อยโดยการลบข้อมูลซ้ำ
ตัวอย่างเช่นเพจ ListEmployee สามารถเข้าถึงได้โดย URL ปกติ - (/ workers / listemployee) และโดย URL แบบสั้น - (/ workers / list)
แทรกเซสชันไฮเบอร์เนตลงในหน้ารายการโดยใช้คำอธิบายประกอบ @Inject กำหนดคุณสมบัติgetEmployeesในหน้ารายการและเติมข้อมูลให้กับพนักงานโดยใช้อ็อบเจ็กต์เซสชั่นที่ถูกแทรก กรอกรหัสสำหรับชั้นพนักงานตามที่แสดงด้านล่าง
ListEmployee.java
package com.example.MyFirstApplication.pages.employee;
import java.util.List;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;
import com.example.MyFirstApplication.entities.Employee;
import org.apache.tapestry5.annotations.Import;
@Import(stylesheet="context:mybootstrap/css/bootstrap.css")
public class ListEmployee {
@Inject
private Session session;
public List<Employee> getEmployees() {
return session.createCriteria(Employee.class).list();
}
}
สร้างไฟล์เทมเพลตสำหรับคลาส ListEmployee แม่แบบจะมีองค์ประกอบหลัก 2 ส่วน ได้แก่ -
PageLink - สร้างหน้าลิงค์พนักงาน
Grid- ใช้เพื่อแสดงรายละเอียดพนักงาน คอมโพเนนต์กริดมีแอตทริบิวต์ต้นทางเพื่อแทรกรายชื่อพนักงานและรวมแอตทริบิวต์เพื่อรวมฟิลด์ที่จะแสดงผล
ListEmployee.tml (รายชื่อพนักงานทั้งหมด)
<html t:type = "simplelayout" title = "List Employee"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<h1>Employees</h1>
<ul>
<li><t:pagelink page = "employee/create">Create new employee</t:pagelink></li>
</ul>
<t:grid source = "employees"
include = "userName,firstName,lastName,gender,dateOfBirth,phone,city,state"/>
</html>
สร้างไฟล์เทมเพลตการสร้างพนักงานและรวมส่วนประกอบ BeanEditForm ส่วนประกอบมีคุณสมบัติดังต่อไปนี้ -
object - รวมแหล่งที่มา
reorder - กำหนดลำดับของฟิลด์ที่จะแสดงผล
submitlabel - ข้อความของปุ่มส่งแบบฟอร์ม
การเข้ารหัสที่สมบูรณ์มีดังนี้ -
<html t:type = "simplelayout" title = "Create New Address"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<t:beaneditform
object = "employee"
submitlabel = "message:submit-label"
reorder = "userName,password,firstName,lastName,
dateOfBirth,gender,email,phone,s treet,city,state,zip" />
</html>
สร้างคลาสการสร้างพนักงานและรวมเซสชันคุณสมบัติของพนักงานหน้ารายการ (ลิงก์การนำทาง) และกำหนดเหตุการณ์ OnSuccess (ที่สำหรับอัปเดตข้อมูล) ของคอมโพเนนต์ ข้อมูลเซสชันจะยังคงอยู่ในฐานข้อมูลโดยใช้เซสชันไฮเบอร์เนต
การเข้ารหัสที่สมบูรณ์มีดังนี้ -
package com.example.MyFirstApplication.pages.employee;
import com.example.MyFirstApplication.entities.Employee;
import com.example.MyFirstApplication.pages.employee.ListEmployee;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;
public class CreateEmployee {
@Property
private Employee employee;
@Inject
private Session session;
@InjectPage
private ListEmployee listPage;
@CommitAfter
Object onSuccess() {
session.persist(employee);
return listPage;
}
}
เพิ่มไฟล์ CreateEmployee.propertiesไฟล์และรวมข้อความที่จะใช้ในการตรวจสอบแบบฟอร์ม รหัสที่สมบูรณ์มีดังนี้ -
zip-regexp=^\\d{5}(-\\d{4})?$
zip-regexp-message = Zip Codes are five or nine digits. Example: 02134 or 901251655.
submit-label = Create Employee
ภาพหน้าจอของหน้าการสร้างพนักงานและหน้ารายชื่อแสดงอยู่ด้านล่าง -
ทุกเว็บแอปพลิเคชันควรมีวิธีการจัดเก็บข้อมูลผู้ใช้บางอย่างเช่นอ็อบเจ็กต์ผู้ใช้ค่ากำหนดของผู้ใช้ ฯลฯ ตัวอย่างเช่นในแอปพลิเคชันตะกร้าสินค้าควรบันทึกรายการ / ผลิตภัณฑ์ที่ผู้ใช้เลือกไว้ในที่เก็บข้อมูลชั่วคราว (ตะกร้า) จนกว่าผู้ใช้จะชอบ เพื่อซื้อผลิตภัณฑ์ เราสามารถบันทึกรายการในฐานข้อมูลได้ แต่จะมีราคาแพงเกินไปเนื่องจากผู้ใช้ทั้งหมดจะไม่ซื้อรายการที่เลือก ดังนั้นเราจำเป็นต้องมีการจัดเตรียมชั่วคราวเพื่อจัดเก็บ / คงอยู่ของรายการ Apache Tapestry มีสองวิธีในการเก็บรักษาข้อมูลและคือ -
- ข้อมูลหน้าการคงอยู่
- พื้นที่จัดเก็บเซสชัน
ทั้งสองมีข้อดีและข้อ จำกัด ในตัวเอง เราจะตรวจสอบในส่วนต่อไปนี้
ข้อมูลหน้าความคงอยู่
Persistence Page Data เป็นแนวคิดง่ายๆในการคงข้อมูลไว้ในหน้าเดียวระหว่างคำขอและเรียกอีกอย่างว่าเป็น Page Level Persistence. สามารถทำได้โดยใช้ไฟล์@Persist คำอธิบายประกอบ
@Persist
public int age;
เมื่อมีการใส่คำอธิบายประกอบด้วย @Persist แล้วค่าของฟิลด์จะยังคงอยู่ตลอดการร้องขอและหากค่ามีการเปลี่ยนแปลงในระหว่างการร้องขอฟิลด์จะแสดงเมื่อมีการเข้าถึงในครั้งต่อไป Apache Tapestry มีกลยุทธ์ห้าประเภทในการนำแนวคิด @Persist ไปใช้ มีดังนี้ -
Session Strategy - ข้อมูลยังคงอยู่โดยใช้เซสชันและเป็นกลยุทธ์เริ่มต้น
Flash Strategy- ข้อมูลยังคงอยู่โดยใช้เซสชันเช่นกัน แต่เป็นข้อมูลที่มีอายุสั้นมาก ข้อมูลจะพร้อมใช้งานในคำขอถัดไปเพียงรายการเดียว
@Persist(PersistenceConstants.FLASH)
private int age;
Client Strategy - ข้อมูลยังคงอยู่ในฝั่งไคลเอ็นต์เช่นสตริงการสืบค้น URL ฟิลด์ที่ซ่อนอยู่ในแบบฟอร์มเป็นต้น
@Persist(PersistenceConstants.FLASH)
private int age;
Hibernate Entity Strategy- ข้อมูลยังคงอยู่โดยใช้โมดูลไฮเบอร์เนตเป็นเอนทิตี เอนทิตีจะถูกเก็บไว้ในไฮเบอร์เนตและการอ้างอิง (ชื่อคลาส Java และคีย์หลัก) จะถูกบันทึกเป็นโทเค็นในHttpSession. เอนทิตีจะถูกกู้คืนโดยใช้โทเค็นที่มีอยู่ใน HttpSession
@Persist(HibernatePersistenceConstants.ENTITY)
private Category category;
JPA Entity Strategy- ข้อมูลยังคงอยู่โดยใช้โมดูล JPA มันจะเก็บเอนทิตีได้เท่านั้น
@Persist(JpaPersistenceConstants.ENTITY)
private User user;
พื้นที่จัดเก็บเซสชัน
พื้นที่จัดเก็บเซสชันเป็นแนวคิดขั้นสูงที่ใช้ในการจัดเก็บข้อมูลที่จำเป็นต้องมีในเพจต่างๆเช่นข้อมูลในวิซาร์ดหลายเพจล็อกอินรายละเอียดผู้ใช้ ฯลฯ ที่เก็บข้อมูลเซสชันมีสองตัวเลือกตัวเลือกหนึ่งในการจัดเก็บอ็อบเจ็กต์ที่ซับซ้อนและอีกตัวหนึ่งเพื่อเก็บค่าอย่างง่าย
Session Store Object - ใช้เพื่อเก็บวัตถุที่ซับซ้อน
Session Attributes - ใช้เพื่อเก็บค่าง่ายๆ
วัตถุที่เก็บเซสชัน (SSO)
สามารถสร้าง SSO ได้โดยใช้ @SessionStoreคำอธิบายประกอบ สปส. จะจัดเก็บวัตถุโดยใช้ชนิดของวัตถุ ตัวอย่างเช่นไฟล์Cart Objectจะถูกจัดเก็บโดยใช้ชื่อคลาส Cart เป็นโทเค็น ดังนั้นสามารถจัดเก็บวัตถุที่ซับซ้อนได้หนึ่งครั้งในแอปพลิเคชัน (หนึ่งรายการต่อผู้ใช้)
public class MySSOPage {
@SessionState
private ShoppingCart cart;
}
SSO เป็นร้านค้าเฉพาะและควรใช้เพื่อเก็บเฉพาะวัตถุที่ซับซ้อน / พิเศษ นอกจากนี้ยังสามารถจัดเก็บประเภทข้อมูลอย่างง่ายโดยใช้ SSO แต่การจัดเก็บประเภทข้อมูลอย่างง่ายเช่น String ทำให้เก็บค่า“ String” ได้เพียงค่าเดียวในแอปพลิเคชัน การใช้ค่า "สตริง" เดียวในแอปพลิเคชันนั้นไม่สามารถทำได้ คุณสามารถใช้ประเภทข้อมูลง่ายๆได้เนื่องจาก Apache Tapestry มีคุณสมบัติเซสชัน
แอตทริบิวต์เซสชัน
แอตทริบิวต์เซสชันช่วยให้สามารถจัดเก็บข้อมูลโดยใช้ชื่อแทนที่จะเป็นประเภท
public class MyPage {
@SessionAttribute
private String loggedInUsername;
}
โดยค่าเริ่มต้นแอตทริบิวต์เซสชันจะใช้ชื่อฟิลด์เพื่ออ้างอิงข้อมูลในเซสชัน เราสามารถเปลี่ยนชื่ออ้างอิงด้วยพารามิเตอร์คำอธิบายประกอบดังที่แสดงด้านล่าง -
public class MyPage {
@SessionAttribute("loggedInUserName")
private String userName;
}
ปัญหาหลักอย่างหนึ่งในการใช้ชื่อเป็นการอ้างอิงเซสชันคือเราอาจใช้ชื่อเดียวกันโดยไม่ได้ตั้งใจในมากกว่าหนึ่งชั้นเรียน / หน้า ในกรณีนี้ข้อมูลที่จัดเก็บอาจเปลี่ยนแปลงโดยไม่คาดคิด ในการแก้ไขปัญหานี้ควรใช้ชื่อร่วมกับชื่อคลาส / เพจและชื่อแพ็กเกจเช่นcom.myapp.pages.register.emailโดยที่ com.myapp.pages เป็นชื่อแพ็กเกจ register คือชื่อเพจ / คลาสและสุดท้ายอีเมลเป็นชื่อตัวแปร (ที่จะจัดเก็บ)
ในบทนี้เราจะพูดถึงคุณสมบัติขั้นสูงบางประการของ Apache Tapestry โดยละเอียด
การผกผันของการควบคุม
Tapestry มีไลบรารี Inversion of Control ในตัว Tapestry ถูกรวมเข้ากับ IoC อย่างลึกซึ้งและใช้ IoC สำหรับคุณสมบัติทั้งหมด การกำหนดค่า Tapestry IoC ขึ้นอยู่กับ Java เองแทนที่จะเป็น XML เหมือนคอนเทนเนอร์ IoC อื่น ๆ โมดูลที่ใช้ Tapestry IoC จะรวมอยู่ในไฟล์ JAR และเพิ่งทิ้งลงใน classpath โดยไม่มีการกำหนดค่าเป็นศูนย์ การใช้งาน Tapestry IoC ขึ้นอยู่กับความเบาซึ่งหมายความว่า -
อินเทอร์เฟซขนาดเล็กสองหรือสามวิธี
วิธีการเล็ก ๆ ที่มีพารามิเตอร์สองหรือสามตัว
การสื่อสารแบบไม่ระบุตัวตนผ่านเหตุการณ์แทนที่จะเรียกใช้วิธีการที่ชัดเจน
โมดูล
โมดูลเป็นวิธีขยายการทำงานของแอปพลิเคชัน Tapestry Tapestry มีทั้งโมดูลในตัวและโมดูลของบุคคลที่สามจำนวนมาก Hibernate เป็นหนึ่งในโมดูลที่ร้อนและมีประโยชน์มากโดย Tapestry นอกจากนี้ยังมีโมดูลที่รวม JMX, JPA, Spring Framework, JSR 303 Bean Validation, JSON และอื่น ๆ โมดูลของบุคคลที่สามที่โดดเด่นบางส่วน ได้แก่ -
- 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
ข้อยกเว้นรันไทม์
หนึ่งในคุณสมบัติที่ดีที่สุดของพรมคือ Detailed Error Reporting. Tapestry ช่วยนักพัฒนาโดยจัดทำรายงานข้อยกเว้นที่ทันสมัย รายงานข้อยกเว้น Tapestry เป็น HTML แบบง่ายพร้อมข้อมูลโดยละเอียด ทุกคนสามารถเข้าใจรายงานได้อย่างง่ายดาย Tapestry แสดงข้อผิดพลาดใน HTML รวมทั้งบันทึกข้อยกเว้นในข้อความธรรมดาพร้อมวันที่และเวลาที่เกิดข้อยกเว้น สิ่งนี้จะช่วยให้นักพัฒนาสามารถตรวจสอบข้อยกเว้นในสภาพแวดล้อมการผลิตได้เช่นกัน นักพัฒนาสามารถมั่นใจในการแก้ไขปัญหาต่างๆเช่นเทมเพลตที่ใช้งานไม่ได้ค่า null ที่ไม่คาดคิดคำขอที่ไม่ตรงกันเป็นต้น
กำลังโหลดคลาสสดและเทมเพลตอีกครั้ง
Tapestry จะโหลดเทมเพลตและคลาสใหม่โดยอัตโนมัติเมื่อแก้ไข คุณสมบัตินี้ช่วยให้สามารถสะท้อนการเปลี่ยนแปลงของแอปพลิเคชันได้ทันทีโดยไม่ต้องผ่านรอบการสร้างและทดสอบ นอกจากนี้คุณสมบัตินี้ยังช่วยเพิ่มประสิทธิภาพการทำงานของการพัฒนาแอปพลิเคชัน
พิจารณาแพ็คเกจรูทของแอปพลิเคชันคือ org.example.myfirstapp. จากนั้นคลาสในพา ธ ต่อไปนี้จะถูกสแกนเพื่อโหลดซ้ำ
- org.example.myfirstapp.pages
- org.example.myfirstapp.components
- org.example.myfirstapp.mixins
- org.example.myfirstapp.base
- org.example.myfirstapp.services
การรีโหลดคลาสสดสามารถปิดใช้งานได้โดยตั้งค่าโหมดการผลิตเป็น true ใน AppModule.java.
configuration.add(SymbolicConstants.PRODUCTION_MODE,”false”);
การทดสอบหน่วย
การทดสอบหน่วยเป็นเทคนิคที่ใช้ทดสอบแต่ละหน้าและส่วนประกอบ Tapestry มีตัวเลือกที่ง่ายในการจัดหน่วยหน้าทดสอบและส่วนประกอบต่างๆ
หน้าทดสอบหน่วย: Tapestry จัดให้มีชั้นเรียน PageTesterเพื่อทดสอบแอปพลิเคชัน ซึ่งทำหน้าที่เป็นทั้งเบราว์เซอร์และคอนเทนเนอร์ servlet มันแสดงผลเพจโดยไม่มีเบราว์เซอร์ในฝั่งเซิร์ฟเวอร์และสามารถตรวจสอบเอกสารผลลัพธ์เพื่อการแสดงผลที่ถูกต้อง พิจารณาหน้าง่ายๆHelloซึ่งแสดงผลสวัสดีและข้อความสวัสดีอยู่ภายในองค์ประกอบ html ที่มี id hello_id. ในการทดสอบคุณสมบัตินี้เราสามารถใช้ PageTester ดังที่แสดงด้านล่าง -
public class PageTest extends Assert {
@Test
public void test1() {
Sring appPackage = "org.example.myfirstapp"; // package name
String appName = "App1"; // app name
PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");
Document doc = tester.renderPage("Hello");
assertEquals(doc.getElementById("hello_id").getChildText(), "hello");
}
}
PageTester ยังมีตัวเลือกในการรวมข้อมูลบริบทการส่งแบบฟอร์มการนำทางลิงก์ ฯลฯ นอกเหนือจากการแสดงผลเพจ
การทดสอบแบบบูรณาการ
การทดสอบแบบรวมช่วยในการทดสอบแอปพลิเคชันเป็นโมดูลแทนที่จะตรวจสอบแต่ละหน้าเหมือนในการทดสอบหน่วย ในการทดสอบแบบรวมสามารถทดสอบหลายโมดูลร่วมกันเป็นหน่วยได้ Tapestry มีห้องสมุดขนาดเล็กที่เรียกว่าTapestry Test Utilitiesทำการทดสอบแบบบูรณาการ ไลบรารีนี้รวมเข้ากับเครื่องมือทดสอบซีลีเนียมเพื่อทำการทดสอบ ไลบรารีจัดเตรียมคลาสพื้นฐานSeleniumTestCaseซึ่งเริ่มต้นและจัดการเซิร์ฟเวอร์ Selenium ไคลเอนต์ Selenium และ Jetty Instance
หนึ่งในตัวอย่างของการทดสอบแบบรวมมีดังนี้ -
import org.apache.tapestry5.test.SeleniumTestCase;
import org.testng.annotations.Test;
public class IntegrationTest extends SeleniumTestCase {
@Test
public void persist_entities() {
open("/persistitem");
assertEquals(getText("//span[@id='name']").length(), 0);
clickAndWait("link = create item");
assertText("//span[@id = 'name']", "name");
}
}
แดชบอร์ดการพัฒนา
แดชบอร์ดการพัฒนาเป็นเพจเริ่มต้นที่ใช้เพื่อระบุ / แก้ไขปัญหาในแอปพลิเคชันของคุณ แดชบอร์ดเข้าถึงได้โดย URLhttp://localhost:8080/myfirstapp/core/t5dashboard. แดชบอร์ดจะแสดงเพจบริการและไลบรารีคอมโพเนนต์ทั้งหมดที่มีอยู่ในแอปพลิเคชัน
การบีบอัดการตอบสนอง
Tapestry บีบอัดการตอบสนองโดยอัตโนมัติโดยใช้ GZIP compressionและสตรีมไปยังไคลเอนต์ คุณลักษณะนี้จะช่วยลดปริมาณการใช้งานเครือข่ายและช่วยให้การส่งเพจเร็วขึ้น การบีบอัดสามารถกำหนดค่าได้โดยใช้สัญลักษณ์tapestry.min-gzip-sizeใน AppModule.java ค่าเริ่มต้นคือ 100 ไบต์ Tapestry จะบีบอัดการตอบสนองเมื่อขนาดของการตอบสนองเกิน 100 ไบต์
ความปลอดภัย
Tapestry มีตัวเลือกมากมายในการรักษาความปลอดภัยแอปพลิเคชันจากช่องโหว่ด้านความปลอดภัยที่ทราบในเว็บแอปพลิเคชัน บางส่วนของตัวเลือกเหล่านี้แสดงอยู่ด้านล่าง -
HTTPS - หน้า Tapestry สามารถใส่คำอธิบายประกอบได้ @Secure เพื่อให้เป็นเพจที่ปลอดภัยและเข้าถึงได้โดยไฟล์ https protocol เท่านั้น.
Page access control - การควบคุมเพจที่จะเข้าถึงได้โดยผู้ใช้บางคนเท่านั้น
White-Listed Page - หน้า Tapestry สามารถใส่คำอธิบายประกอบด้วยไฟล์ @WhitelistAccessOnly เพื่อให้สามารถเข้าถึงได้ผ่านไฟล์ localhost.
Asset Security- ภายใต้ผ้าม่านคุณสามารถเข้าถึงไฟล์บางประเภทเท่านั้น ผู้อื่นสามารถเข้าถึงได้ก็ต่อเมื่อไฟล์MD5 hash ของไฟล์มีให้
Serialized Object Date - Tapestry รวม HMAC เข้ากับข้อมูลวัตถุ Java ที่ต่อเนื่องกันและส่งไปยังไคลเอนต์เพื่อหลีกเลี่ยงการปลอมแปลงข้อความ
Cross Site Request Forgery- พรมมี 3 ถโมดูลของบุคคลที่เรียกว่าพรม-CSRF ป้องกันเพื่อป้องกันการโจมตี CSRF ใด ๆ
Security Framework integration- Tapestry ไม่ได้ล็อคการใช้งานการพิสูจน์ตัวตน / การอนุญาตเพียงครั้งเดียว Tapestry สามารถรวมเข้ากับเฟรมเวิร์กการพิสูจน์ตัวตนยอดนิยม
การบันทึก
Tapestry ให้การสนับสนุนอย่างกว้างขวางสำหรับการบันทึกการบันทึกความคืบหน้าของแอปพลิเคชันโดยอัตโนมัติในขณะที่ทำงาน Tapestry ใช้ไลบรารีการบันทึก Java โดยพฤตินัยSLF4J. คำอธิบายประกอบ@Logสามารถอยู่ในเมธอดคอมโพเนนต์ใดก็ได้เพื่อปล่อยการเข้าและออกของเมธอดและข้อยกเว้นที่เป็นไปได้เช่นกัน นอกจากนี้วัตถุ Tapestry ที่ให้มาคนตัดไม้สามารถฉีดเข้าไปในส่วนประกอบใดก็ได้โดยใช้ไฟล์@Inject คำอธิบายประกอบดังแสดงด้านล่าง -
public class MyPage {
@Inject
private Logger logger;
// . . .
void onSuccessFromForm() {
logger.info("Changes saved successfully");
}
@Log
void onValidateFromForm() {
// logic
}
}
สุดท้ายนี้เราสามารถพูดได้ว่า Apache Tapestry นำเสนอวิธีที่ดีที่สุดในการสร้างแอปพลิเคชั่นที่กระชับปรับขนาดได้บำรุงรักษาได้แข็งแกร่งและเปิดใช้งาน Ajax Tapestry สามารถรวมเข้ากับแอปพลิเคชัน Java ของ บริษัท อื่นได้ นอกจากนี้ยังสามารถช่วยในการสร้างเว็บแอปพลิเคชันขนาดใหญ่ได้เนื่องจากค่อนข้างง่ายและรวดเร็ว