ไลบรารีรีซอร์ส JSF คืออะไรและควรใช้อย่างไร?


228

JSF <h:outputStylesheet>, <h:outputScript>และ<h:graphicImage>ส่วนประกอบมีlibraryแอตทริบิวต์ สิ่งนี้คืออะไรและควรใช้สิ่งนี้อย่างไร มีตัวอย่างจำนวนมากบนเว็บที่ใช้ดังต่อไปนี้กับเนื้อหา / ประเภทไฟล์cssทั่วไปjsและimg(หรือimage) เป็นชื่อไลบรารีขึ้นอยู่กับแท็กที่ใช้:

<h:outputStylesheet library="css" name="style.css" />
<h:outputScript library="js" name="script.js" />
<h:graphicImage library="img" name="logo.png" />

มันมีประโยชน์อย่างไร? libraryค่าในตัวอย่างเหล่านั้นดูเหมือนว่าจะเป็นเพียงแค่การทำซ้ำสิ่งที่จะได้รับแล้วแสดงโดยแท็กชื่อ สำหรับ<h:outputStylesheet>มันขึ้นอยู่กับชื่อแท็กแล้วชัดเจนว่ามันหมายถึง "ห้องสมุด CSS" อะไรคือความแตกต่างของสิ่งต่อไปนี้ที่ใช้งานได้เหมือนกัน?

<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />

นอกจากนี้เอาต์พุต HTML ที่สร้างขึ้นนั้นแตกต่างกันเล็กน้อย กำหนดเส้นทางบริบท/contextnameและFacesServletการแมปบนรูปแบบ URL ของ*.xhtmlอดีตสร้าง HTML ต่อไปนี้ด้วยชื่อไลบรารีเป็นพารามิเตอร์คำขอ:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/style.css.xhtml?ln=css" />
<script type="text/javascript" src="/contextname/javax.faces.resource/script.js.xhtml?ln=js"></script>
<img src="/contextname/javax.faces.resource/logo.png.xhtml?ln=img" alt="" />

ในขณะที่หลังสร้าง HTML ต่อไปนี้ด้วยชื่อไลบรารีเพียงในเส้นทางของ URI:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml" alt="" />

วิธีการหลังทำให้รู้สึกถึงปัญหาย้อนหลังได้มากกว่าวิธีเดิม วิธีการว่าเป็นlibraryคุณลักษณะที่มีประโยชน์แล้ว?

คำตอบ:


256

ที่จริงแล้วทั้งหมดของตัวอย่างผู้ที่อยู่ในเว็บนั้นเนื้อหาทั่วไปประเภทไฟล์ / เช่น "js", "CSS", "img" ฯลฯ จะถูกนำมาใช้เป็นชื่อห้องสมุดจะทำให้เข้าใจผิด

ตัวอย่างโลกแห่งความจริง

ในการเริ่มต้นดูให้ของที่ใช้งาน JSF วิธีการที่มีอยู่เช่นกระโดงและMyFacesและ JSF ห้องสมุดส่วนประกอบเช่นPrimeFacesและOmniFacesใช้มัน ไม่มีใครใช้ไลบรารีทรัพยากรด้วยวิธีนี้ พวกเขาใช้มัน (ภายใต้หน้ากากโดย@ResourceDependencyหรือUIViewRoot#addComponentResource()) วิธีต่อไปนี้:

<h:outputScript library="javax.faces" name="jsf.js" />
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:outputScript library="omnifaces" name="omnifaces.js" />
<h:outputScript library="omnifaces" name="fixviewstate.js" />
<h:outputScript library="omnifaces.combined" name="[dynamicname].js" />
<h:outputStylesheet library="primefaces" name="primefaces.css" />
<h:outputStylesheet library="primefaces-aristo" name="theme.css" />
<h:outputStylesheet library="primefaces-vader" name="theme.css" />

มันควรจะชัดเจนว่ามันแสดงถึงชื่อไลบรารี / โมดูล / ธีมโดยทั่วไปซึ่งทรัพยากรเหล่านั้นทั้งหมดเป็นของ

ระบุได้ง่ายขึ้น

วิธีนี้จะง่ายกว่ามากในการระบุและแยกแยะว่าทรัพยากรเหล่านั้นเป็นของและ / หรือมาจากที่ใด ลองนึกภาพว่าคุณมีprimefaces.cssทรัพยากรในเว็บแอปของคุณเองซึ่งคุณจะสามารถเอาชนะ / ตรวจสอบ CSS เริ่มต้นของ PrimeFaces; หาก PrimeFaces ไม่ได้ใช้ชื่อไลบรารีเป็นของตัวเองprimefaces.cssแล้ว PrimeFaces นั้นจะไม่ถูกโหลด แต่จะแทนการโหลดจากเว็บแอปซึ่งจะทำลาย look'n'feel แทน

นอกจากนี้เมื่อคุณใช้งานแบบกำหนดเองResourceHandlerคุณยังสามารถใช้การควบคุมที่ละเอียดยิ่งขึ้นของทรัพยากรที่มาจากไลบรารีเฉพาะเมื่อlibraryใช้อย่างถูกวิธี หากไลบรารีคอมโพเนนต์ทั้งหมดจะใช้ "js" สำหรับไฟล์ JS ทั้งหมดจะResourceHandlerแยกแยะว่ามาจากไลบรารีคอมโพเนนต์เฉพาะได้อย่างไร ตัวอย่างคือ OmniFaces CombinedResourceHandlerและGraphicResourceHandler; ตรวจสอบcreateResource()เมธอดที่ไลบรารีถูกตรวจสอบก่อนมอบหมายให้ตัวจัดการรีซอร์สถัดไปในเชน วิธีนี้พวกเขารู้ว่าเมื่อใดที่จะสร้างCombinedResourceหรือGraphicResourceเพื่อวัตถุประสงค์

ควรสังเกตว่า RichFaces ทำผิด มันไม่ได้ใช้งานเลยlibraryและ homebrewed การจัดการทรัพยากรอีกชั้นเหนือชั้นและดังนั้นจึงเป็นไปไม่ได้ที่จะระบุทรัพยากร RichFaces โดยทางโปรแกรม นั่นคือเหตุผลที่ว่าทำไมOmniFaces CombinedResourceHanderจึงต้องแนะนำการแฮ็กตามการสะท้อนกลับเพื่อให้สามารถทำงานได้ด้วยทรัพยากร RichFaces

เว็บแอปของคุณเอง

เว็บแอปของคุณเองไม่จำเป็นต้องมีไลบรารีทรัพยากร คุณควรละเว้นมัน

<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />

หรือถ้าคุณต้องการชื่อจริงคุณสามารถตั้งชื่อสามัญที่สมเหตุสมผลได้เช่น "ค่าเริ่มต้น" หรือชื่อ บริษัท บางชื่อ

<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />

หรือเมื่อทรัพยากรมีเฉพาะกับเทมเพลต Facelets ต้นแบบบางอย่างคุณสามารถตั้งชื่อเทมเพลตเพื่อให้สามารถเชื่อมโยงซึ่งกันและกันได้ง่ายขึ้น กล่าวอีกอย่างหนึ่งก็คือมันมีไว้สำหรับวัตถุประสงค์ในการถ่ายทำสารคดี เช่นใน/WEB-INF/templates/layout.xhtmlไฟล์เทมเพลต:

<h:outputStylesheet library="layout" name="css/style.css" />
<h:outputScript library="layout" name="js/script.js" />

และ/WEB-INF/templates/admin.xhtmlไฟล์เทมเพลต:

<h:outputStylesheet library="admin" name="css/style.css" />
<h:outputScript library="admin" name="js/script.js" />

สำหรับตัวอย่างที่โลกแห่งความจริงตรวจสอบOmniFaces การแสดงรหัสที่มา

หรือเมื่อคุณต้องการแบ่งปันทรัพยากรเดียวกันผ่านหลาย webapps และได้สร้างโครงการ "ทั่วไป" สำหรับสิ่งนั้นขึ้นอยู่กับตัวอย่างเช่นเดียวกับในคำตอบนี้ซึ่งฝังตัวเป็น JAR ใน webapp ของ/WEB-INF/libแล้วอ้างอิงมันเป็นห้องสมุด (ชื่อฟรีสำหรับตัวเลือกของคุณไลบรารีองค์ประกอบเช่น OmniFaces และ PrimeFaces ก็ทำงานเช่นนั้น):

<h:outputStylesheet library="common" name="css/style.css" />
<h:outputScript library="common" name="js/script.js" />
<h:graphicImage library="common" name="img/logo.png" />

การกำหนดเวอร์ชันของไลบรารี

ข้อได้เปรียบที่สำคัญอีกประการหนึ่งคือคุณสามารถใช้ไลบรารี่รุ่นที่เหมาะสมกับทรัพยากรที่มาจากเว็บแอพของคุณเอง คุณสามารถสร้างโฟลเดอร์ย่อยย่อยโดยตรงในโฟลเดอร์ไลบรารีที่มีชื่อใน\d+(_\d+)*รูปแบบเพื่อแสดงเวอร์ชันไลบรารีทรัพยากร

WebContent
 |-- resources
 |    `-- default
 |         `-- 1_0
 |              |-- css
 |              |    `-- style.css
 |              |-- img
 |              |    `-- logo.png
 |              `-- js
 |                   `-- script.js
 :

เมื่อใช้มาร์กอัปนี้:

<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />

สิ่งนี้จะสร้าง HTML ต่อไปนี้พร้อมกับเวอร์ชันไลบรารีเป็นvพารามิเตอร์:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&amp;v=1_0" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&amp;v=1_0"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&amp;v=1_0" alt="" />

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

ดังนั้นเมื่อคัดลอก / เปลี่ยนชื่อresources/default/1_0/*โฟลเดอร์เป็นresources/default/1_1/*ดังนี้:

WebContent
 |-- resources
 |    `-- default
 |         |-- 1_0
 |         |    :
 |         |
 |         `-- 1_1
 |              |-- css
 |              |    `-- style.css
 |              |-- img
 |              |    `-- logo.png
 |              `-- js
 |                   `-- script.js
 :

จากนั้นตัวอย่างมาร์กอัพสุดท้ายจะสร้าง HTML ต่อไปนี้:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&amp;v=1_1" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&amp;v=1_1"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&amp;v=1_1" alt="" />

สิ่งนี้จะบังคับให้เว็บเบราเซอร์ร้องขอทรัพยากรโดยตรงจากเซิร์ฟเวอร์แทนการแสดงชื่อที่มีชื่อเดียวกันจากแคชเมื่อ URL ที่มีการเปลี่ยนแปลงพารามิเตอร์ถูกร้องขอเป็นครั้งแรก วิธีนี้ผู้ใช้ไม่จำเป็นต้องทำการรีเฟรชอย่างหนัก (Ctrl + F5 และอื่น ๆ ) เมื่อต้องการเรียกคืนทรัพยากร CSS / JS ที่อัปเดต

โปรดทราบว่าการกำหนดรุ่นไลบรารี่เป็นไปไม่ได้สำหรับทรัพยากรที่อยู่ในไฟล์ JAR ResourceHandlerคุณจะต้องกำหนดเอง ดูเพิ่มเติมวิธีการใช้ JSF เวอร์ชันสำหรับทรัพยากรในโถ

ดูสิ่งนี้ด้วย:


2
เป็นไปได้ไหมที่จะใช้ EL สำหรับห้องสมุด? ดังนั้นหากฉันต้องการมีทรัพยากร / ค่าเริ่มต้นและแหล่งข้อมูล / ความรู้สึกของโฟกกี้วันนี้ฉันสามารถทำอะไรบางอย่างเช่นไลบรารี่ = "# {someLibraryHere}" แมปไลบรารี่ไลบรารีที่นี่ที่ห้องสมุดที่ฉันเลือกและไม่ต้องพึ่งพาการเปลี่ยนไดเรกทอรีไดเรกทอรี ฉันต้องการเปลี่ยนพวกเขา
gebuh

เมื่อคุณพูดว่า library = admin หรือ libray = layout โฟลเดอร์เหล่านั้น (admin และ layout) ในโฟลเดอร์ทรัพยากรหรือไม่
Koray Tugay

อืมมม Balus ที่น่าสนใจมาก ฉันประสบปัญหาในเว็บแอปที่ไฟล์ theme.css หายไปเมื่อทำการโหลด สิ่งนี้จะเกิดขึ้นหลังจาก redeploys ต่างๆ (ใน JBOSS EAP) URL css เป็นเช่นนี้: /javax.faces.resource/css/theme.css.xhtml?ln=default&v=3_3_0_130416 และมีการประกาศด้วยวิธีนี้: <h: outputStylesheet library = "default" name = "css / theme css "target =" head "/> บางทีปัญหานี้เกี่ยวข้องกับปัญหาเกี่ยวกับเวอร์ชันหรือไม่
Ricardo Vila

2
อักขระที่อนุญาตสำหรับค่าlibraryหรือบางอย่างเกี่ยวข้องกับมันเปลี่ยนแปลงระหว่าง mojarra 2.2.5 (2.2.5-jbossorg-3, wildfly 8.0) และ 2.2.11 (2.2.11-jbossorg-1) หรือไม่ ฉันดูเหมือนจะไม่พบสิ่งใดใน releasenotes ดูstackoverflow.com/questions/35719808/…
Kukeltje

3
ขอบคุณ @BalusC แต่น่าเสียดายที่แม้ของออราเคิลเอง Java EE 7 สอนให้เป็นตัวอย่างที่ไม่ถูกต้องโดยใช้ชื่อไลบรารีcssในบทที่8.6 แหล่งข้อมูลบนเว็บและทำมันผิดด้วย CSS และภาพในการประยุกต์ใช้เช่น GuessNumber-JSF
Jesper
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.