JSF คืออะไร? ขอแนะนำ JavaServer Faces

JavaServer Faces (JSF) เป็นเทคโนโลยีมาตรฐานของ Java สำหรับการสร้างเว็บอินเตอร์เฟสที่เน้นองค์ประกอบตามเหตุการณ์ เช่นเดียวกับ JavaServer Pages (JSP) JSF อนุญาตให้เข้าถึงข้อมูลและตรรกะฝั่งเซิร์ฟเวอร์ แตกต่างจาก JSP ซึ่งโดยพื้นฐานแล้วเพจ HTML เต็มไปด้วยความสามารถฝั่งเซิร์ฟเวอร์ JSF เป็นเอกสาร XML ที่แสดงส่วนประกอบที่เป็นทางการในโครงสร้างแบบลอจิคัล คอมโพเนนต์ JSF ได้รับการสนับสนุนโดยอ็อบเจ็กต์ Java ซึ่งไม่ขึ้นอยู่กับ HTML และมีความสามารถ Java แบบเต็มรูปแบบรวมถึงการเข้าถึง API และฐานข้อมูลระยะไกล

ความคิดที่สำคัญในกรอบเช่น JSF คือการแค็ปซูล (หรือห่อ ) เทคโนโลยีฝั่งไคลเอ็นต์เช่น HTML, CSS และ JavaScript ช่วยให้นักพัฒนาสร้างอินเตอร์เฟซเว็บโดยไม่มีการโต้ตอบมากกับเทคโนโลยีเหล่านี้

บทความนี้นำเสนอภาพรวมของแนวทางของ JSF ในการพัฒนา UI ตามคอมโพเนนต์สำหรับเว็บแอปพลิเคชัน Java ตัวอย่างง่ายๆแนะนำสถาปัตยกรรม MVC ของ JSF โมเดลเหตุการณ์และไลบรารีคอมโพเนนต์ ตัวอย่าง ได้แก่ คุณลักษณะใหม่ใน JSF 2.3 และเราจะใช้ PrimeFaces สำหรับไลบรารีคอมโพเนนต์ของเรา

การพัฒนา JSF

JSF ได้รับความนิยมมายาวนานเมื่อไม่นานมานี้ต้องเผชิญกับการแข่งขันจากเว็บเฟรมเวิร์กที่เข้ากันได้กับ Java รวมถึงเฟรมเวิร์ก JavaScript ฝั่งไคลเอ็นต์ อย่างไรก็ตาม JavaServer Faces ยังคงเป็นมาตรฐาน Java โดยเฉพาะอย่างยิ่งสำหรับการพัฒนาองค์กร Java ขนาดใหญ่ ข้อกำหนด JSF ยังสร้างเฟรมเวิร์กและไลบรารีจำนวนมากซึ่งก้าวไปพร้อมกับการปรับปรุงฝั่งไคลเอ็นต์ล่าสุด หนึ่งในนั้นคือ PrimeFaces ซึ่งเราสำรวจในบทช่วยสอนนี้

แม้ว่ากำหนดการสำหรับการพัฒนาในอนาคตจะไม่ชัดเจน แต่ JSF 2.3 ก็ให้นักพัฒนาทำงานมากมายในขณะที่เรารอ เผยแพร่ในเดือนมีนาคม 2017 JSF 2.3 ได้รับการออกแบบโดยเจตนาเพื่อปรับปรุง JSF ให้ทันสมัย ในบรรดาการซ่อมแซมขนาดเล็กหลายร้อยรายการและการอัปเดตที่ใหญ่กว่านั้น JSF 2.3 จะเลิกใช้คำอธิบายประกอบ bean ที่มีการจัดการเพื่อสนับสนุน CDI ซึ่งฉันจะแนะนำในภายหลังในบทช่วยสอนนี้

JSF 2.3 ใน Jakarta EE

ในเดือนกันยายน 2017 Oracle ได้ประกาศความตั้งใจที่จะเปลี่ยน Java EE ไปเป็น Eclipse Foundation Java EE ได้ถูกเปลี่ยนชื่อเป็น Jakarta EE และมีการนำ JSF 2.3 (Eclipse Mojarra) มาใช้เพื่อดำเนินการต่อ ข้อกำหนด JSF รุ่นหลักถัดไปจะเป็น Eclipse Mojarra 3.0

การสร้างเว็บอินเตอร์เฟสที่ใช้คอมโพเนนต์ใน JSF

แนวคิดหลักของ JSF คือการรวมฟังก์ชันการทำงานไว้ในส่วนประกอบที่ใช้ซ้ำได้ ซึ่งคล้ายกับแท็กที่ใช้ซ้ำได้ที่ใช้ใน JSP แต่คอมโพเนนต์ JSF มีความเป็นทางการมากกว่า

แม้ว่าคุณจะสามารถใช้เพจ JSF ภายใน JavaServer Pages ได้ แต่การใช้ Facelets เพื่อสร้างเพจ JSF แบบสแตนด์อโลนเป็นเรื่องปกติ Faceletsคือหน้า XHTML ที่ออกแบบมาเพื่อกำหนดอินเทอร์เฟซ JSF ด้วย Facelets คุณใช้แท็ก XML เพื่อสร้างโครงสร้างส่วนประกอบที่กลายเป็นโครงสำหรับส่วนติดต่อผู้ใช้ JSF

รายการ 1 แสดงส่วนหลักของหน้า JSF แบบง่ายที่เขียนโดยใช้ Facelets ในตัวอย่างนี้เรากำลังเข้าถึงความสามารถฝั่งเซิร์ฟเวอร์ของ Java ผ่าน bean ที่วางไว้ในขอบเขตผ่าน CDI คุณจะเห็นข้อมูลเพิ่มเติมเกี่ยวกับ CDI ในภายหลัง

รายการ 1. หน้าตัวอย่าง JSF

    Hello JavaWorld!   #{javaBean.content}  

ในรายการ 1 เราจะเห็นหน้า XHTML มาตรฐาน มุมมอง Facelets สร้างขึ้นที่ด้านบนของ XHTML นอกเหนือจากเนมสเปซ XHTML แล้วยังมีการกำหนดและอ้างอิงเนมสเปซรอง

hห้องสมุดมีชิ้นส่วนมาตรฐานสำหรับการใช้งานในหน้าเว็บ HTML JSF //xmlns.jcp.org/jsf/htmlห้องสมุดกำหนดคอลเลกชันของ JSF ส่วนประกอบในกรณีนี้คอลเลกชันขององค์ประกอบ HTML ทั่วไป หนึ่งในองค์ประกอบเหล่านี้คือองค์ประกอบ

ส่วนประกอบ HTML ใน JSF

ในแง่ของไวยากรณ์องค์ประกอบของ Listing 1 อ้างอิงjsf/htmlไลบรารีด้วยhคำนำหน้า จากนั้นอ้างอิงองค์ประกอบเฉพาะภายในไลบรารีซึ่งเป็นheadส่วนประกอบ

องค์ประกอบ outputs องค์ประกอบหัวของ HTML (ไวยากรณ์ทั้งหมดนั้นอาจดูเหมือนมากเกินไปสำหรับจุดประสงค์ง่ายๆเช่นนี้ แต่มีเหตุผลที่ดีสำหรับมันดังที่คุณจะเห็นในไม่ช้า)

ส่วนประกอบการทำรัง

ภายในส่วนหัวมีองค์ประกอบHTML มาตรฐานซ้อนอยู่ องค์ประกอบนี้ถูกจัดเตรียมให้กับคอมโพเนนต์พร้อมกับองค์ประกอบย่อยของเนื้อหาที่ซ้อนอยู่ภายในองค์ประกอบนั้น

ในเนื้อหาของเอกสารนิพจน์ JSF มีอยู่ใน#{}ไวยากรณ์ สิ่งนี้คล้ายคลึงกับนิพจน์ JSP ที่มี${}รูปแบบ: อนุญาตให้เข้าถึงวัตถุ Java ในขอบเขตและฟังก์ชันง่ายๆ

รูปแบบพื้นฐานสำหรับ JSF นั้นเรียบง่าย: ใช้ Facelets เพื่อสร้างแผนผัง XML ที่อ้างอิงไลบรารีคอมโพเนนต์หรือไลบรารีจากนั้นใช้คอมโพเนนต์ภายในไลบรารีเพื่อแสดงวัตถุ Java เป็น HTML

การใช้วัตถุ Java ใน JSF

กลับไปที่ Listing 1 สังเกตว่าภายในนิพจน์ JSF ( ${javaBean.content) javaBeanอ็อบเจ็กต์อยู่ในขอบเขตเมื่อดำเนินการมาร์กอัปนี้ XHTML ของ Facelets เข้าถึง.contentคุณสมบัติบนjavaBeanวัตถุ ผลลัพธ์สุดท้ายคือเว็บอินเตอร์เฟสที่ผสานโครงสร้างมุมมอง Facelets เข้ากับข้อมูลฝั่งเซิร์ฟเวอร์ของ Java และความสามารถด้านตรรกะ

การใช้นิพจน์ JSF เป็นเพียงวิธีหนึ่งในการเข้าถึงข้อมูลแอ็พพลิเคชัน Java จากอินเทอร์เฟซผู้ใช้ JSF ในที่สุดคุณจะต้องสำรวจวิธีอื่น ๆ ที่คอมโพเนนต์ JSF สามารถโต้ตอบกับแบ็กเอนด์ Java ได้เช่นรายการข้อมูลและกริดและการควบคุมอินพุตต่างๆ สำหรับตอนนี้มันเพียงพอแล้วที่จะเข้าใจว่า JSF ใช้แท็ก XML (หรือคำอธิบายประกอบ) เพื่อสร้างโครงสร้างของส่วนประกอบที่ส่งออก HTML ตามข้อมูลที่มีอยู่ในวัตถุ Java อย่างไร

คำอธิบายประกอบกับ XML

ด้วย JSF 2.3 ทำให้สามารถกำหนดคอมโพเนนต์ JSF พร้อมคำอธิบายประกอบการละเว้นข้อมูลเมตาของ XML ทั้งหมด เป็นไปได้อย่างเต็มที่ในการกำหนดและปรับใช้แอป JSF โดยไม่ต้องแก้ไข XML ใด ๆ

โครงสร้างของแอปพลิเคชัน JSF

เช่นเดียวกับ JavaServer Pages และ Servlet API JavaServer Faces ต้องการโครงสร้างไดเร็กทอรีมาตรฐานและข้อมูลเมตา สิ่งเหล่านี้ถูกปรับใช้เป็นไฟล์. war

โครงสร้างของไฟล์. war คล้ายกับแอปพลิเคชัน Servlet หรือ JSP ประกอบด้วย/web-appไดเร็กทอรีซึ่งเก็บไฟล์มาร์กอัปของแอปพลิเคชัน (ในกรณีนี้คือ HTML, JSP และ Facelets) รวมถึง/WEB-INFไดเร็กทอรีซึ่งนำเสนอข้อมูลเมตาเพื่ออธิบายแอปพลิเคชัน

ให้บริการ JSF

แม้ว่าคุณจะสามารถรัน JSF ในคอนเทนเนอร์ Java EE เช่น Glassfish ได้ แต่คอนเทนเนอร์ servlet แบบธรรมดาก็เป็นสิ่งที่คุณต้องการจริงๆ Tomcat เป็นคอนเทนเนอร์ยอดนิยมสำหรับ JSF และเทคโนโลยี Java ฝั่งเซิร์ฟเวอร์อื่น ๆ

JSF 2.3: ข้อมูลจำเพาะและการใช้งาน

จุดแข็งอย่างหนึ่งของ Java คือมันเป็นไปตามมาตรฐานและมาตรฐานเหล่านั้นถูกควบคุมโดยกระบวนการชุมชนโอเพ่นซอร์ส ตั้งแต่เริ่มก่อตั้ง Java Community Process (JCP) ได้ดูแลการพัฒนาเทคโนโลยี Java เมื่อ JCP พัฒนาและรับรองคุณสมบัติเฉพาะหรือข้อกำหนดแล้วจะสามารถนำไปใช้งานได้จากหลายฝ่าย จนกระทั่งเมื่อไม่นานนี้ Servlets, JSP และ JSF ได้รับการพัฒนาโดยใช้กระบวนการข้อกำหนดโอเพนซอร์สของ JCP

ข้อมูลจำเพาะ JSF ล่าสุดในงานเขียนนี้คือ JSF 2.3 ซึ่งเผยแพร่เป็นส่วนหนึ่งของ Java EE 8 ในปี 2017 Mojarra ของ Oracle (ปัจจุบันคือ Eclipse's) เป็นการนำไปใช้งานอ้างอิง JSF และ MyFaces และ PrimeFaces เป็นการนำไปใช้งานของบุคคลที่สามที่เป็นที่นิยม

แต่ละเฟรมเวิร์กเหล่านี้ใช้แกน JSF ซึ่งรวมถึงส่วนประกอบมาตรฐานบางอย่าง ผู้ขายอาจเสนอไลบรารีส่วนประกอบเพิ่มเติมที่ด้านบนของมาตรฐาน เมื่อประเมินเฟรมเวิร์ก JSF คุณควรพิจารณาความต้องการของแอปพลิเคชันของคุณและไลบรารีคอมโพเนนต์ใดที่สามารถช่วยคุณสร้างได้ ตามหลักการแล้วกรอบงาน JSF ของคุณควรทำให้คุณเข้าใกล้สิ่งที่คุณต้องการได้มากที่สุดเท่าที่จะทำได้ทันที

MVC ใน JSF 2.3

JSF เป็นเฟรมเวิร์ก MVCซึ่งใช้รูปแบบ model-view-controller ในรูปแบบ MVC แนวคิดคือการแยกข้อกังวลสามประการของ UI ออกเป็นส่วนที่รอบคอบเพื่อให้จัดการได้ง่ายขึ้น โดยทั่วไปมุมมองมีหน้าที่ในการแสดงข้อมูลในโมเดลและคอนโทรลเลอร์มีหน้าที่ในการตั้งค่าโมเดลและกำหนดเส้นทางผู้ใช้ไปยังมุมมองที่ถูกต้อง

ในการใช้งาน JSF มุมมองคือหน้า Facelets พร้อมชุดแท็ก XML สิ่งเหล่านี้กำหนดโครงร่างของอินเทอร์เฟซผู้ใช้ อีกครึ่งหนึ่งของการใช้ JSF คือฝั่งเซิร์ฟเวอร์โดยที่คลาส Java จะสนับสนุนส่วนประกอบ UI เหล่านั้น

ถั่วจัดการเลิกใช้งานใน JSF 2.3

คำอธิบายประกอบ bean ที่มีการจัดการได้เลิกใช้แล้วใน JSF 2.3 และแทนที่ด้วย CDI (Contexts and Dependency Injection) ด้วย CDI นักพัฒนาจะกำหนดบริบทและฉีดวัตถุไปยังบริบทนั้น ผู้ที่คุ้นเคยกับถั่วที่มีการจัดการจะพบว่าไวยากรณ์คำอธิบายประกอบแตกต่างกันเล็กน้อย แต่ความหมายยังคงเหมือนเดิมทุกประการ

ถั่วควบคุม

ใน JSF 2.3 ถั่วคอนโทรลเลอร์จัดเตรียมส่วนควบคุมของสมการ MVC อ็อบเจ็กต์ Java ปกติ (มักเรียกว่า POJO หรืออ็อบเจ็กต์ Java แบบเก่า) จัดเตรียมโมเดล

ในแง่ของการไหลของกระบวนการถั่วควบคุม:

  1. ตัดสินใจว่าจะส่งคำขอของผู้ใช้ไปที่ใด
  2. ตั้งค่า POJO สำหรับโมเดล
  3. ใช้โมเดลเพื่อแสดงมุมมอง Facelets

จากนั้น JSF จะพับโครงสร้างองค์ประกอบและโมเดลเข้าด้วยกันเพื่อแสดงผล HTML ที่ส่งออก

รายการ 2 แสดงวิธีกำหนดjavaBeanวัตถุจากรายการ 1 โดยใช้ CDI รายการนี้ถือว่าแอปพลิเคชันมี cdi-api-1.2.jar ในการอ้างอิง

รายการ 2. JavaBean กำหนดโดยใช้ CDI

 import javax.inject.Named; import javax.enterprise.context.SessionScoped; @Named @ViewScoped public class JavaBean implements Serializable { private String content = ìWelcome to JSF!î // getters/setters } 

JSF 2.3 พร้อม PrimeFaces

ในส่วนถัดไปฉันจะใช้ PrimeFaces เพื่อแสดงให้คุณเห็นว่า JSF ใช้รูปแบบ MVC การส่งข้อความตามเหตุการณ์และส่วนประกอบที่ใช้ซ้ำได้อย่างไร ในการเริ่มต้นเปิดโชว์ PrimeFaces คลิกข้อมูลการเชื่อมโยงในคอลัมน์ด้านซ้ายและเลือกDataList สิ่งนี้จะดึงโค้ดสาธิต DataList สำหรับ PrimeFaces

รูปที่ 1 แสดงให้คุณเห็นว่าจะหาตัวอย่างเหล่านี้ได้ที่ไหน

Matthew Tyson

รูปที่ 2 แสดงผลลัพธ์ของตารางข้อมูลอย่างง่ายซึ่งนำมาจากการสาธิต PrimeFaces DataList

Matthew Tyson

PrimeFaces DataList: การเข้าถึงโมเดลข้อมูล

Listing 3 presents the markup for this dataList display. If you scroll to the bottom of the PrimeFaces showcase, you can see the markup in the dataList.xhtml tab.

Listing 3. Facelet for PrimeFaces DataList

   Basic  #{car.brand}, #{car.year}  

In Listing 3, notice the value property of the dataList component. You can see that this references a dataListView object, and accesses the .cars1 property on it. The component is going to use the model object returned by that field. JSF tokens use conventional accessors to reference object properties, so .cars1 will refer to the getCars() getter on the object.

Next, notice the var="car" property. This tells the dataList component what variable to use when it iterates over the list of cars returned by the value field. These properties are specific to the dataList component, but the value property is very common. The var attribute is also conventional for components that iterate over lists.

In the body of the component in Listing 3, you can see the car variable is accessed via JSF expressions like #{car.brand}. Each iteration of the dataListView.cars1 instance will output the car.brand field.

Notice that the tag demonstrates the ability to customize components for how they will display. In this case, the header is defined as Basic.

You can see how the Facelets XML will drive this output by combining the data with the markup. Now let's look at the Java code behind it.

DataList's server-side components

Listing 4 shows DataListView, the Java class that is used by the markup in Listing 3. You'll see shortly how the dataListView instance is associated with the DataListView class.

Listing 4. DataListView class

 package org.primefaces.showcase.view.data; import java.io.Serializable; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Named; // Pre JSF 2.3, this was: // import javax.faces.bean.ManagedBean; import javax.inject.Inject; import javax.faces.bean.ViewScoped; import org.primefaces.showcase.domain.Car; import org.primefaces.showcase.service.CarService; @Named @ViewScoped public class DataListView implements Serializable { private List cars1; private Car selectedCar; @Inject("#{carService}") private CarService service; @PostConstruct public void init() { cars1 = service.createCars(10); } public List getCars1() { return cars1; } public void setService(CarService service) { this.service = service; } } 

Listing 4 has a few other important elements, which we'll consider piece by piece.

Dependency injection and annotations

First, notice that the DataListView class is annotated with @Named, which you can see from the import import javax.inject.Named; is part of JSF. The @Named annotation tells JSF this bean is part of the app. The @ViewScoped annotation informs JSF that the bean will live for just the life of the view.

ถัดไปสังเกตว่าCarServiceคุณสมบัติมี@Injectคำอธิบายประกอบ (เรียกว่า@ManagedPropertyก่อนหน้า JSF 2.3) นี่เป็นอีกคุณสมบัติหนึ่งของ JSF ที่ช่วยให้สามารถ "ต่อสายเข้าด้วยกัน" ซึ่งเป็นเทคนิคที่ได้รับความนิยมจาก Spring framework และเครื่องมือฉีดพึ่งพาอื่น ๆ โดยพื้นฐานแล้ว JSF จะค้นหาcarServiceวัตถุในขอบเขตและเชื่อมโยงโดยอัตโนมัติกับserviceฟิลด์บนDataListViewวัตถุ