บทนำ
เมื่อใดก็ตามที่UICommand
องค์ประกอบ ( <h:commandXxx>
, <p:commandXxx>
ฯลฯ ) ล้มเหลวในการเรียกใช้วิธีการกระทำที่เกี่ยวข้องหรือUIInput
ส่วนประกอบ ( <h:inputXxx>
, <p:inputXxxx>
ฯลฯ ) ล้มเหลวในการประมวลผลค่าที่ส่งและ / หรืออัปเดตค่ารุ่นและคุณไม่เห็นข้อยกเว้น googlable และ / หรือ คำเตือนในบันทึกของเซิร์ฟเวอร์ยังไม่ได้เมื่อคุณกำหนดค่าการจัดการข้อยกเว้นอาแจ็กซ์เป็นต่อในการจัดการ JSF คำขอ Ajax ข้อยกเว้นหรือเมื่อคุณตั้งค่าพารามิเตอร์ด้านล่างบริบทweb.xml
,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
และคุณยังไม่เห็นข้อผิดพลาดของ googlable และ / หรือคำเตือนในคอนโซล JavaScript ของเบราว์เซอร์ (กด F12 ใน Chrome / Firefox23 + / IE9 + เพื่อเปิดชุดเครื่องมือสำหรับนักพัฒนาเว็บและเปิดแท็บคอนโซล ) จากนั้นทำตามรายการด้านล่าง
สาเหตุที่เป็นไปได้
UICommand
และUIInput
ส่วนประกอบต้องอยู่ภายในUIForm
ส่วนประกอบเช่น<h:form>
(และไม่ใช่ HTML ธรรมดา<form>
) มิฉะนั้นจะไม่มีสิ่งใดถูกส่งไปยังเซิร์ฟเวอร์ UICommand
ส่วนประกอบต้องไม่มีtype="button"
แอตทริบิวต์มิฉะนั้นจะเป็นปุ่มตายซึ่งมีประโยชน์สำหรับ JavaScript onclick
เท่านั้น ดูเพิ่มเติมวิธีการส่งค่าที่ป้อนเข้ารูปแบบและวิธีการในการเรียก JSF ถั่วและ<H: CommandButton> ไม่ได้เริ่มต้นการ postback
คุณไม่สามารถซ้อนหลายUIForm
องค์ประกอบในกันและกัน นี่เป็นสิ่งผิดกฎหมายใน HTML พฤติกรรมของเบราว์เซอร์ไม่ได้ระบุ ระวังด้วยไฟล์รวม! คุณสามารถใช้UIForm
ส่วนประกอบในแบบคู่ขนาน แต่จะไม่ประมวลผลซึ่งกันและกันระหว่างการส่ง คุณควรระวังด้วย antipattern "God Form" ตรวจสอบให้แน่ใจว่าคุณไม่ได้ดำเนินการโดยไม่ตั้งใจ / ตรวจสอบอินพุตอื่น (มองไม่เห็น) ทั้งหมดในรูปแบบเดียวกัน (เช่นมีกล่องโต้ตอบที่ซ่อนอยู่พร้อมกับอินพุตที่ต้องการในรูปแบบเดียวกันมาก) ดูวิธีใช้ <h: form> ในหน้า JSF ได้อย่างไร แบบฟอร์มเดียว? หลายรูปแบบ? แบบฟอร์มซ้อนกัน? .
ไม่UIInput
ควรมีข้อผิดพลาดในการตรวจสอบความถูกต้อง / การแปลงค่า คุณสามารถใช้<h:messages>
เพื่อแสดงข้อความใด ๆ ที่ไม่ได้แสดงโดย<h:message>
ส่วนประกอบเฉพาะอินพุตใด ๆ อย่าลืมที่จะรวมid
ของ<h:messages>
ใน<f:ajax render>
กรณีใด ๆ เพื่อที่มันจะได้รับการปรับปรุงเช่นเดียวกับการร้องขอของอาแจ็กซ์ ดูเพิ่มเติมH: ข้อความไม่แสดงข้อความเมื่อ P: CommandButton กด
หากUICommand
หรือUIInput
ส่วนประกอบถูกวางไว้ภายในองค์ประกอบการวนซ้ำเช่น<h:dataTable>
, <ui:repeat>
ฯลฯ คุณต้องแน่ใจว่าvalue
องค์ประกอบการวนซ้ำนั้นถูกเก็บรักษาไว้อย่างแน่นอนในระหว่างขั้นตอนการร้องขอค่าของการใช้แบบฟอร์มส่งคำขอ JSF จะทำซ้ำเพื่อหาลิงก์ / ปุ่มที่คลิกและค่าอินพุตที่ส่ง การวาง bean ในขอบเขตมุมมองและ / หรือตรวจสอบให้แน่ใจว่าคุณโหลดโมเดลข้อมูลใน@PostConstruct
bean (และไม่ใช่วิธี getter!) ควรแก้ไข ดูเพิ่มเติมอย่างไรและเมื่อฉันควรโหลดรูปแบบจากฐานข้อมูลสำหรับ H:
หากส่วนประกอบUICommand
หรือUIInput
รวมอยู่ในแหล่งที่มาแบบไดนามิกเช่น<ui:include src="#{bean.include}">
นั้นคุณจะต้องให้แน่ใจว่า#{bean.include}
ค่าเดียวกันจะถูกเก็บไว้ในช่วงเวลาที่สร้างมุมมองของการร้องขอการส่งแบบฟอร์ม JSF จะดำเนินการอีกครั้งในระหว่างการสร้างแผนภูมิองค์ประกอบ การวาง bean ในขอบเขตมุมมองและ / หรือตรวจสอบให้แน่ใจว่าคุณโหลดโมเดลข้อมูลใน@PostConstruct
bean (และไม่ใช่วิธี getter!) ควรแก้ไข ดูเพิ่มเติมวิธีการ ajax-refresh dynamic รวมเนื้อหาตามเมนูการนำทาง (JSF สปา)
rendered
แอตทริบิวต์ขององค์ประกอบและทั้งหมดของพ่อแม่และtest
แอตทริบิวต์ของผู้ปกครอง<c:if>
/ <c:when>
ไม่ควรประเมินfalse
ในระหว่างการปรับใช้ค่าการร้องขอขั้นตอนของการส่งแบบฟอร์มคำขอ JSF จะตรวจสอบอีกครั้งว่าเป็นส่วนหนึ่งของการป้องกันการร้องขอดัดแปลง / แฮ็ก การจัดเก็บตัวแปรที่รับผิดชอบต่อเงื่อนไขใน@ViewScoped
ถั่วหรือตรวจสอบให้แน่ใจว่าคุณกำหนดค่าเริ่มต้นอย่างเหมาะสมในสภาพ@PostConstruct
ของ@RequestScoped
ถั่วควรแก้ไข เช่นเดียวกับdisabled
คุณลักษณะของส่วนประกอบซึ่งไม่ควรประเมินtrue
ในระหว่างขั้นตอนการใช้ค่าคำขอ ดูเพิ่มเติมกระทำ JSF CommandButton ไม่เรียก , แบบฟอร์มส่งในองค์ประกอบที่แสดงผลตามเงื่อนไขจะไม่ประมวลผลและH: CommandButton ไม่ทำงานเมื่อฉันห่อไว้ใน <H: panelGroup แสดงผล>
onclick
แอตทริบิวต์ของUICommand
องค์ประกอบและonsubmit
แอตทริบิวต์ของUIForm
องค์ประกอบที่ไม่ควรจะกลับfalse
หรือก่อให้เกิดข้อผิดพลาด JavaScript ในกรณีที่มี<h:commandLink>
หรือ<f:ajax>
ไม่มีข้อผิดพลาด JS ที่มองเห็นได้ในคอนโซล JS ของเบราว์เซอร์ โดยปกติแล้ว googling ข้อความแสดงข้อผิดพลาดที่แน่นอนจะให้คำตอบแล้ว ดูเพิ่มเติมด้วยตนเองเพิ่ม / โหลด jQuery กับ PrimeFaces ผลลัพธ์ใน TypeErrors
หากคุณกำลังใช้อาแจ็กซ์ผ่าน 2.x JSF <f:ajax>
หรือเช่น PrimeFaces <p:commandXxx>
ตรวจสอบให้แน่ใจว่าคุณมีในแม่แบบหลักแทน<h:head>
<head>
มิฉะนั้น JSF จะไม่สามารถรวมไฟล์ JavaScript ที่จำเป็นซึ่งมีฟังก์ชัน Ajax ได้โดยอัตโนมัติ ซึ่งจะส่งผลให้เกิดข้อผิดพลาด JavaScript เช่น "mojarra ไม่ได้ถูกกำหนด" หรือ "PrimeFaces ไม่ได้กำหนด" ในคอนโซล JS ของเบราว์เซอร์ ดูเพิ่มเติมH: commandLink ActionListener ไม่ได้เรียกเมื่อใช้กับ f: อาแจ็กซ์และ UI:
หากคุณกำลังใช้อาแจ็กซ์และค่าส่งจบลงด้วยการnull
แล้วให้แน่ใจว่าUIInput
และUICommand
ส่วนประกอบที่สนใจที่ได้รับความคุ้มครองโดย<f:ajax execute>
หรือเช่น<p:commandXxx process>
มิฉะนั้นพวกเขาจะไม่ได้รับการดำเนินการ / การประมวลผล ดูเพิ่มเติมค่าแบบฟอร์มการส่งไม่ได้ปรับปรุงในรูปแบบเมื่อมีการเพิ่ม <f: อาแจ็กซ์> ไปที่ <H: CommandButton>และPrimeFaces ทำความเข้าใจขั้นตอน / อัปเดตและ JSF f: อาแจ็กซ์รัน / ทำให้คุณลักษณะ
หากค่าที่ส่งยังคงเป็นอยู่null
และคุณใช้ CDI ในการจัดการ beans จากนั้นตรวจสอบให้แน่ใจว่าคุณได้นำเข้าคำอธิบายประกอบขอบเขตจากแพคเกจที่ถูกต้องมิฉะนั้น CDI จะเริ่มต้นที่จะ@Dependent
สร้างถั่วขึ้นใหม่ทุกครั้ง การแสดงออก ดูเพิ่มเติมที่@SessionScoped bean จะสูญเสียขอบเขตและได้รับการสร้างใหม่ตลอดเวลาฟิลด์กลายเป็นโมฆะและManaged Bean Scope เริ่มต้นในแอปพลิเคชัน JSF 2 คืออะไร
หากผู้ปกครองของ<h:form>
กับUICommand
ปุ่มรับก่อนการแสดงผล / การปรับปรุงโดยการร้องขอมาจากอาแจ็กซ์ฟอร์มในหน้าเดียวกันอีกแล้วดำเนินการครั้งแรกมักจะล้มเหลวในการ JSF 2.2 หรือมากกว่า การกระทำที่สองและที่ตามมาจะทำงาน ปัญหานี้เกิดจากข้อบกพร่องในการจัดการสถานะมุมมองซึ่งรายงานว่าเป็นปัญหาเฉพาะของ JSF 790และในปัจจุบันได้รับการแก้ไขใน JSF 2.3 สำหรับรุ่นเก่า JSF คุณจะต้องระบุอย่างชัดเจน ID ของ<h:form>
ในของrender
<f:ajax>
ดูเพิ่มเติมที่h: commandButton / h: commandLink ไม่ทำงานเมื่อคลิกครั้งแรกใช้ได้กับการคลิกครั้งที่สองเท่านั้น
หาก<h:form>
มีการenctype="multipart/form-data"
ตั้งค่าไว้เพื่อรองรับการอัปโหลดไฟล์คุณจะต้องตรวจสอบให้แน่ใจว่าคุณใช้ JSF 2.2 เป็นอย่างน้อยหรือว่าตัวกรองเซิร์ฟเล็ตที่รับผิดชอบในการแยกวิเคราะห์คำขอแบบหลายส่วน / แบบฟอร์มข้อมูลถูกต้องมิฉะนั้นFacesServlet
จะ ท้ายไม่ได้รับพารามิเตอร์คำขอเลยและไม่สามารถใช้ค่าคำขอได้ วิธีกำหนดค่าตัวกรองดังกล่าวจะขึ้นอยู่กับองค์ประกอบการอัพโหลดไฟล์ที่ใช้ สำหรับ Tomahawk <t:inputFileUpload>
ตรวจสอบคำตอบนี้และสำหรับ PrimeFaces <p:fileUpload>
ให้ตรวจสอบคำตอบนี้ หรือหากคุณไม่ได้อัปโหลดไฟล์จริงๆให้ลบแอตทริบิวต์ทั้งหมด
ตรวจสอบให้แน่ใจว่าActionEvent
อาร์กิวเมนต์ของactionListener
เป็น javax.faces.event.ActionEvent
และไม่ใช่java.awt.event.ActionEvent
ซึ่งเป็นสิ่งที่ IDEs ส่วนใหญ่แนะนำให้เป็นตัวเลือกการเติมข้อความอัตโนมัติครั้งที่ 1 actionListener="#{bean.method}"
มีข้อโต้แย้งที่ไม่เป็นธรรมเช่นกันถ้าคุณใช้ actionListener="#{bean.method()}"
หากคุณไม่ต้องการข้อโต้แย้งในการที่คุณใช้ หรือบางทีคุณอาจต้องการจริงที่จะใช้แทนaction
actionListener
ดูเพิ่มเติมความแตกต่างระหว่างการกระทำและ ActionListener
ตรวจสอบให้แน่ใจว่าไม่มีPhaseListener
หรือEventListener
ในห่วงโซ่ตอบสนองการร้องขอมีการเปลี่ยนแปลงวงจรชีวิต JSF ที่จะข้ามขั้นตอนการดำเนินการโดยวิงวอนขอยกตัวอย่างเช่นการเรียกหรือFacesContext#renderResponse()
FacesContext#responseComplete()
ตรวจสอบให้แน่ใจว่าไม่มีFilter
หรือServlet
ในห่วงโซ่การตอบสนองคำขอเดียวกันได้ปิดกั้นการร้องขอFacesServlet
อย่างใด ตัวอย่างเช่นตัวกรองล็อกอิน / ความปลอดภัยเช่น Spring Security โดยเฉพาะอย่างยิ่งในคำขอ ajax ที่โดยค่าเริ่มต้นจะไม่มีความคิดเห็น UI เลย ดูเพิ่มเติมฤดูใบไม้ผลิการรักษาความปลอดภัยที่ 4 และ PrimeFaces จัดการคำขอ
หากคุณกำลังใช้ PrimeFaces <p:dialog>
หรือแล้วให้แน่ใจว่าพวกเขามีของตัวเอง<p:overlayPanel>
<h:form>
เพราะองค์ประกอบเหล่านี้โดยการเริ่มต้นโดย JavaScript ย้ายไปอยู่ที่ปลาย <body>
HTML ดังนั้นหากพวกเขากำลังนั่งอยู่เดิมภายในแล้วพวกเขาก็จะตอนนี้ไม่ได้อีกต่อไปนั่งอยู่ใน<form>
<form>
ดูเพิ่มเติมที่p: การดำเนินการ commandbutton ไม่ทำงานภายในกล่องโต้ตอบ p:
บั๊กในเฟรมเวิร์ก ตัวอย่างเช่น RichFaces มี " ข้อผิดพลาดในการแปลง " เมื่อใช้rich:calendar
องค์ประกอบ UI ที่มีdefaultLabel
แอตทริบิวต์ (หรือในบางกรณีเป็นrich:placeholder
องค์ประกอบย่อย) ข้อผิดพลาดนี้จะป้องกันไม่ให้เรียกใช้วิธี bean เมื่อไม่มีการตั้งค่าสำหรับวันที่ในปฏิทิน การติดตามข้อบกพร่องของเฟรมเวิร์กสามารถทำได้โดยเริ่มจากตัวอย่างการทำงานที่เรียบง่ายและการสร้างหน้าสำรองจนกว่าจะพบข้อบกพร่อง
การดีบักคำแนะนำ
ในกรณีที่คุณยังคงติดอยู่ก็ถึงเวลาที่จะแก้ไขข้อบกพร่อง ในฝั่งไคลเอ็นต์ให้กด F12 ในเว็บเบราว์เซอร์เพื่อเปิดชุดเครื่องมือสำหรับนักพัฒนาเว็บ คลิกที่แท็บคอนโซลเพื่อดู Conosle JavaScript ควรปราศจากข้อผิดพลาด JavaScript ใด ๆ ภาพหน้าจอด้านล่างเป็นตัวอย่างจาก Chrome ที่แสดงให้เห็นกรณีของการส่ง<f:ajax>
ปุ่มเปิดใช้งานในขณะที่ยังไม่ได้<h:head>
ประกาศ (ดังที่อธิบายไว้ในข้อ 7 ข้างต้น)
คลิกที่แท็บเครือข่ายเพื่อดู HTTP traffic monitor ส่งแบบฟอร์มและตรวจสอบว่าส่วนหัวคำขอและข้อมูลแบบฟอร์มและเนื้อหาการตอบสนองเป็นไปตามความคาดหวัง ภาพหน้าจอด้านล่างเป็นตัวอย่างจาก Chrome ซึ่งแสดงให้เห็นถึงอาแจ็กซ์ประสบความสำเร็จส่งของรูปแบบที่เรียบง่ายมีเพียงหนึ่งเดียว<h:inputText>
และเป็นหนึ่งเดียวกับ<h:commandButton>
<f:ajax execute="@form" render="@form">
(คำเตือน: เมื่อคุณโพสต์ภาพหน้าจอจากส่วนหัวคำขอ HTTP เช่นด้านบนจากสภาพแวดล้อมการใช้งานจริงจากนั้นตรวจสอบให้แน่ใจว่าคุณได้เบราว์เซอร์ / ทำให้งงงวยคุกกี้เซสชันใด ๆ ในภาพหน้าจอเพื่อหลีกเลี่ยงการโจมตี
ในฝั่งเซิร์ฟเวอร์ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์เริ่มทำงานในโหมดแก้ไขข้อบกพร่อง วางจุดพักการดีบักในวิธีการขององค์ประกอบ JSF ที่น่าสนใจซึ่งคุณคาดว่าจะถูกเรียกในระหว่างการประมวลผลแบบฟอร์มส่ง เช่นในกรณีของUICommand
องค์ประกอบที่จะเป็นUICommand#queueEvent()
และในกรณีขององค์ประกอบที่จะเป็นUIInput
UIInput#validate()
เพียงแค่ผ่านการเรียกใช้โค้ดและตรวจสอบว่าโฟลว์และตัวแปรนั้นเป็นไปตามความคาดหวังหรือไม่ ภาพหน้าจอด้านล่างเป็นตัวอย่างจากตัวดีบักของ Eclipse