1. เป้าหมายไม่สามารถเข้าถึงได้ตัวระบุ 'bean' ถูกแก้ไขเป็น null
นี้เดือดลงไปว่าเช่นถั่วที่มีการจัดการตัวเองไม่สามารถพบได้โดยระบุว่าที่ (การจัดการชื่อถั่ว) #{bean}
ในเอเช่นดังนั้น
การระบุสาเหตุสามารถแบ่งออกเป็นสามขั้นตอน:
ก. ใครเป็นคนจัดการถั่ว?
ข. ชื่อถั่วที่มีการจัดการ (ค่าเริ่มต้น) คืออะไร?
ค. ชั้นเรียนถั่วสำรองอยู่ที่ไหน
1a. ใครเป็นคนจัดการถั่ว?
ขั้นตอนแรกคือการตรวจสอบกรอบการจัดการ bean ใดที่รับผิดชอบในการจัดการอินสแตนซ์ bean เป็นJSFผ่าน@ManagedBean
หรือไม่ หรือเป็นCDIผ่าน@Named
? หรือว่าSpringผ่าน@Component
? คุณแน่ใจได้หรือไม่ว่าคุณไม่ได้ผสมคำอธิบายประกอบเฉพาะของกรอบการจัดการถั่วหลายรายการในคลาสถั่วสำรองเดียวกัน เช่น@Named @Component
หรือ@Named @ManagedBean
หรือ@ManagedBean @Component
. นี่เป็นสิ่งที่ไม่ถูกต้อง bean ต้องได้รับการจัดการโดยเฟรมเวิร์กการจัดการ bean มากที่สุดหนึ่งเฟรมเวิร์กและเฟรมเวิร์กนั้นต้องได้รับการกำหนดค่าอย่างเหมาะสม หากคุณไม่มีความคิดที่จะเลือกให้ไปที่Backing beans (@ManagedBean) หรือ CDI Beans (@Named)? และการรวม Spring JSF: วิธีการฉีด Spring component / service ใน JSF Managed bean
ในกรณีที่เป็นJSFที่จัดการ bean ผ่าน@ManagedBean
คุณต้องตรวจสอบสิ่งต่อไปนี้:
การfaces-config.xml
ประกาศรากเข้ากันได้กับ JSF 2.0 ดังนั้นไฟล์ XSD และอย่างน้อยversion
ต้องระบุ JSF 2.0 ขึ้นไปจึงไม่ใช่ 1.x
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
สำหรับ JSF 2.1 เพียงแค่แทนที่2_0
และ2.0
ตาม2_1
และ2.1
ตามลำดับ
หากคุณใช้ JSF 2.2 ขึ้นไปตรวจสอบให้แน่ใจว่าคุณใช้xmlns.jcp.org
เนมสเปซแทนการใช้java.sun.com
ตำแหน่งทั้งหมด
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
สำหรับ JSF 2.3 เพียงแค่แทนที่2_2
และ2.2
ตาม2_3
และ2.3
ตามลำดับ
คุณไม่ได้ตั้งใจนำเข้าแทนjavax.annotation.ManagedBean
javax.faces.bean.ManagedBean
ระวังการเติมข้อความอัตโนมัติ IDE เป็นที่ทราบกันดีว่า Eclipse จะแนะนำข้อผิดพลาดโดยอัตโนมัติเป็นรายการแรกในรายการ
- คุณไม่ได้แทนที่
@ManagedBean
ด้วย<managed-bean>
รายการสไตล์ JSF 1.x ในfaces-config.xml
คลาส bean สำรองเดียวกันพร้อมกับชื่อ bean ที่มีการจัดการอื่น @ManagedBean
หนึ่งในนี้จะมีความสำคัญมากกว่า การลงทะเบียน bean ที่มีการจัดการfaces-config.xml
ไม่จำเป็นเนื่องจาก JSF 2.0 เพียงแค่ลบออก
- คลาสพา ธ รันไทม์ของคุณสะอาดและไม่มีรายการซ้ำใน JAR ที่เกี่ยวข้องกับ JSF API ตรวจสอบให้แน่ใจว่าคุณไม่ได้ผสมการใช้งาน JSF หลายอย่าง (Mojarra และ MyFaces) ตรวจสอบให้แน่ใจว่าคุณไม่ได้ให้ไฟล์ JSF อื่นหรือแม้แต่ไฟล์ Java EE API JAR พร้อมกับเว็บแอปเมื่อคอนเทนเนอร์เป้าหมายรวม JSF API ไว้แล้ว โปรดดูส่วน"การติดตั้ง JSF" ในหน้า JSF wikiสำหรับคำแนะนำในการติดตั้ง JSF ในกรณีที่คุณต้องการอัปเกรด JSF ที่รวมคอนเทนเนอร์จาก WAR บนแทนที่จะเป็นในคอนเทนเนอร์เองตรวจสอบให้แน่ใจว่าคุณได้สั่งให้คอนเทนเนอร์เป้าหมายใช้ JSF API / im ที่รวม WAR
- หากคุณกำลังบรรจุภัณฑ์ JSF การจัดการถั่วในขวดแล้วให้แน่ใจว่า JAR มีอย่างน้อย JSF
/META-INF/faces-config.xml
2.0 ดูวิธีอ้างอิงถั่วที่มีการจัดการ JSF ซึ่งมีให้ในไฟล์ JAR ได้อย่างไร
หากคุณกำลังจริงโดยใช้ 1.x JSF จูราสสิและคุณไม่สามารถอัปเกรดแล้วคุณจำเป็นต้องลงทะเบียนผ่านทางถั่ว<managed-bean>
ในแทนfaces-config.xml
@ManagedBean
อย่าลืมแก้ไขเส้นทางการสร้างโครงการของคุณที่คุณไม่มีไลบรารี JSF 2.x อีกต่อไป (เพื่อไม่ให้@ManagedBean
คำอธิบายประกอบคอมไพล์สำเร็จอย่างสับสน)
ในกรณีที่เป็นCDIที่จัดการถั่ว@Named
คุณต้องตรวจสอบสิ่งต่อไปนี้:
CDI 1.0 (Java EE 6) ต้องการ/WEB-INF/beans.xml
ไฟล์เพื่อเปิดใช้งาน CDI ใน WAR อาจว่างเปล่าหรืออาจมีเพียงเนื้อหาต่อไปนี้:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
CDI 1.1 (Java EE 7)โดยไม่มีไฟล์ใด ๆbeans.xml
หรือbeans.xml
ไฟล์เปล่าหรือด้วยความเข้ากันได้กับ CDI 1.0 ข้างต้นbeans.xml
จะทำงานเหมือนกับ CDI 1.0 เมื่อมีการ CDI 1.1 เข้ากันได้beans.xml
กับอย่างชัดเจนversion="1.1"
แล้วมันจะเป็นค่าเริ่มต้นเพียงลงทะเบียน@Named
ถั่วกับ CDI อย่างชัดเจนขอบเขตคำอธิบายประกอบเช่น@RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
ฯลฯ ในกรณีที่คุณตั้งใจจะลงทะเบียนถั่วทั้งหมดเป็น CDI การจัดการถั่วแม้ที่ไม่มีความชัดเจน ขอบเขต CDI ใช้ CDI 1.1 ด้านล่างที่เข้ากันได้/WEB-INF/beans.xml
กับbean-discovery-mode="all"
ชุด (ค่าเริ่มต้นคือbean-discovery-mode="annotated"
)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
เมื่อใช้ CDI 1.1 ขึ้นไปด้วยbean-discovery-mode="annotated"
(เริ่มต้น) ตรวจสอบให้แน่ใจว่าคุณไม่ได้ตั้งใจนำเข้าขอบเขต JSF เช่นแทนที่จะขอบเขตjavax.faces.bean.RequestScoped
CDI javax.enterprise.context.RequestScoped
ระวังการเติมข้อความอัตโนมัติ IDE
- เมื่อใช้กระโดง 2.3.0-2.3.2 และ CDI 1.1 ขึ้นไปด้วย
bean-discovery-mode="annotated"
(เริ่มต้น) แล้วคุณจะต้องอัพเกรดกระโดงจะ 2.3.3 หรือใหม่กว่าเนื่องจากมีข้อผิดพลาด ในกรณีที่คุณไม่สามารถอัปเกรดแล้วคุณจะต้องทั้งชุดbean-discovery-mode="all"
ในbeans.xml
หรือจะนำเฉพาะ JSF 2.3 @FacesConfig
คำอธิบายประกอบในชั้นเรียนโดยพลการในสงคราม (โดยทั่วไปการจัดเรียงของแอพลิเคชันบางขอบเขตระดับเริ่มต้น)
- คอนเทนเนอร์ EE ที่ไม่ใช่ Java เช่น Tomcat และ Jetty ไม่ได้มาพร้อมกับ CDI ที่แถมมา คุณต้องติดตั้งด้วยตนเอง มันทำงานได้ดีกว่าการเพิ่ม JAR ของไลบรารี สำหรับ Tomcat โปรดทำตามคำแนะนำในคำตอบนี้: จะติดตั้งและใช้ CDI บน Tomcat ได้อย่างไร?
- คลาสพา ธ รันไทม์ของคุณสะอาดและไม่มีรายการซ้ำใน JAR ที่เกี่ยวข้องกับ CDI API ตรวจสอบให้แน่ใจว่าคุณไม่ได้ผสมการใช้งาน CDI หลายอย่าง (Weld, OpenWebBeans ฯลฯ ) ตรวจสอบให้แน่ใจว่าคุณไม่ได้ให้ไฟล์ CDI อื่นหรือแม้แต่ไฟล์ Java EE API JAR บนเว็บแอปเมื่อคอนเทนเนอร์เป้าหมายรวม CDI API ไว้แล้ว
หากคุณบรรจุถั่วที่จัดการ CDI สำหรับมุมมอง JSF ใน JAR ให้ตรวจสอบว่า JAR มีอย่างน้อยที่ถูกต้อง/META-INF/beans.xml
(ซึ่งสามารถเว้นว่างไว้ได้)
ในกรณีที่เป็นฤดูใบไม้ผลิใครเป็นคนจัดการถั่ว@Component
คุณต้องตรวจสอบสิ่งต่อไปนี้:
ฤดูใบไม้ผลิจะถูกติดตั้งและบูรณาการตามเอกสาร สิ่งสำคัญอย่างน้อยคุณต้องมีสิ่งนี้ในweb.xml
:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
และสิ่งนี้ในfaces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(ด้านบนคือทั้งหมดที่ฉันรู้เกี่ยวกับ Spring - ฉันไม่ได้ทำ Spring - อย่าลังเลที่จะแก้ไข / แสดงความคิดเห็นเกี่ยวกับสาเหตุอื่น ๆ ที่เกี่ยวข้องกับ Spring เช่นปัญหาที่เกี่ยวข้องกับการกำหนดค่า XML)
ในกรณีที่มันเป็นองค์ประกอบทวนใครเป็นผู้จัดการ (ที่ซ้อนกัน) ถั่วผ่านทางvar
แอตทริบิวต์ (เช่น<h:dataTable var="item">
, <ui:repeat var="item">
, <p:tabView var="item">
ฯลฯ ) และคุณได้จริง "เป้าหมายไม่สามารถเข้าถึงตัวระบุ 'รายการ' มีมติ null" แล้วคุณต้องให้แน่ใจว่าต่อไปนี้ :
1b. ชื่อถั่วที่มีการจัดการ (ค่าเริ่มต้น) คืออะไร?
ขั้นตอนที่สองคือการตรวจสอบชื่อ bean ที่มีการจัดการที่ลงทะเบียนแล้ว ข้อตกลงการใช้ JSF และ Spring เป็นไปตามข้อกำหนดJavaBeansในขณะที่ CDI มีข้อยกเว้นขึ้นอยู่กับ CDI im / version
FooBean
ระดับการสนับสนุนถั่วเช่นด้านล่าง
@Named
public class FooBean {}
จะในเฟรมเวิร์กการจัดการ bean ทั้งหมดมีชื่อ bean ที่มีการจัดการดีฟอลต์#{fooBean}
ตามข้อกำหนด JavaBeans
FOOBean
ระดับการสนับสนุนถั่วเช่นด้านล่าง
@Named
public class FOOBean {}
ซึ่งชื่อคลาสที่ไม่มีเงื่อนไขเริ่มต้นด้วยตัวพิมพ์ใหญ่อย่างน้อยสองตัวจะอยู่ใน JSF และ Spring มีชื่อ bean ที่มีการจัดการดีฟอลต์ซึ่งเป็นชื่อคลาสที่ไม่มีคุณสมบัติ#{FOOBean}
ตรงตามข้อกำหนดของ JavaBeans ใน CDI นี่เป็นกรณีของ Weld เวอร์ชันที่เผยแพร่ก่อนเดือนมิถุนายน 2015 แต่ไม่ใช่ในเวอร์ชัน Weld ที่วางจำหน่ายหลังเดือนมิถุนายน 2015 (2.2.14 / 2.3.0.B1 / 3.0.0.A9) หรือใน OpenWebBeans เนื่องจากการกำกับดูแลใน ข้อมูลจำเพาะ ในเวอร์ชัน Weld เหล่านั้นและในเวอร์ชัน OWB ทั้งหมดจะมีเฉพาะอักขระตัวแรกที่ลด#{fOOBean}
ลงเท่านั้น
หากคุณระบุชื่อถั่วที่มีการจัดการไว้อย่างชัดเจนfoo
ดังต่อไปนี้
@Named("foo")
public class FooBean {}
หรือเท่ากันด้วย@ManagedBean(name="foo")
หรือ@Component("foo")
แล้วมันจะเพียง แต่จะสามารถใช้ได้โดยการ#{foo}
จึงไม่ได้#{fooBean}
โดย
1 ค. ชั้นเรียนถั่วสำรองอยู่ที่ไหน
ขั้นตอนที่สามจะเป็นการตรวจสอบซ้ำหากคลาสของการสำรองข้อมูลอยู่ในตำแหน่งที่ถูกต้องในไฟล์ WAR ที่สร้างและปรับใช้ ตรวจสอบให้แน่ใจว่าคุณได้ทำการล้างสร้างใหม่ปรับใช้และรีสตาร์ทโปรเจ็กต์และเซิร์ฟเวอร์อย่างถูกต้องในกรณีที่คุณยุ่งอยู่กับการเขียนโค้ดและกด F5 อย่างไม่เต็มใจในเบราว์เซอร์ หากยังไร้ผลให้ระบบบิลด์สร้างไฟล์ WAR จากนั้นคุณจะแตกและตรวจสอบด้วยเครื่องมือ ZIP .class
ไฟล์ที่คอมไพล์ของคลาส bean สำรองต้องอยู่ในโครงสร้างแพ็กเกจใน/WEB-INF/classes
. หรือเมื่อบรรจุเป็นส่วนหนึ่งของโมดูล JAR JAR ที่มี.class
ไฟล์ที่คอมไพล์แล้วจะต้องอยู่ใน/WEB-INF/lib
นั้นดังนั้นจึงไม่ใช่เช่น EAR /lib
หรือที่อื่น ๆ
หากคุณกำลังใช้ Eclipse ตรวจสอบให้แน่ใจว่าคลาสของ backing bean อยู่ในsrc
ดังนั้นจึงไม่ใช่ WebContent
และตรวจสอบให้แน่ใจว่าเปิดใช้งานProject> Build Automaticallyแล้ว หากคุณกำลังใช้ Maven ตรวจสอบให้แน่ใจว่าระดับการสนับสนุนถั่วอยู่ในsrc/main/java
จึงไม่ได้อยู่ในหรือsrc/main/resources
src/main/webapp
หากคุณบรรจุเว็บแอปพลิเคชันเป็นส่วนหนึ่งของ EAR ที่มี EJB + WAR คุณต้องตรวจสอบให้แน่ใจว่าคลาสแบ็คกิ้งบีนอยู่ในโมดูล WAR ดังนั้นจึงไม่อยู่ในโมดูล EAR หรือโมดูล EJB ระดับธุรกิจ (EJB) ต้องปราศจากสิ่งประดิษฐ์ที่เกี่ยวข้องกับระดับเว็บ (WAR) ใด ๆ เพื่อให้ระดับธุรกิจสามารถนำกลับมาใช้ใหม่ได้ในหลาย ๆ เว็บ (JSF, JAX-RS, JSP / Servlet ฯลฯ )
2. เป้าหมายไม่สามารถเข้าถึงได้ 'เอนทิตี' ส่งคืนค่าว่าง
นี้เดือดลงไปว่าที่ซ้อนกันสถานที่ให้บริการentity
ในขณะที่กลับมา#{bean.entity.property}
null
นี้มักจะมีเพียง exposes เมื่อ JSF ความต้องการที่จะตั้งค่าสำหรับการproperty
ผ่านองค์ประกอบการป้อนข้อมูลเช่นนี้ในขณะที่กลับมาจริง#{bean.entity}
null
<h:inputText value="#{bean.entity.property}" />
คุณต้องตรวจสอบให้แน่ใจว่าคุณได้เตรียมเอนทิตีแบบจำลองไว้ล่วงหน้าใน a @PostConstruct
หรือ<f:viewAction>
วิธีการหรืออาจเป็นadd()
วิธีการดำเนินการในกรณีที่คุณกำลังทำงานกับรายการ CRUD และ / หรือกล่องโต้ตอบในมุมมองเดียวกัน
@Named
@ViewScoped
public class Bean {
private Entity entity; // +getter (setter is not necessary).
@Inject
private EntityService entityService;
@PostConstruct
public void init() {
// In case you're updating an existing entity.
entity = entityService.getById(entityId);
// Or in case you want to create a new entity.
entity = new Entity();
}
// ...
}
เกี่ยวกับความสำคัญของ@PostConstruct
; การทำสิ่งนี้ในตัวสร้างปกติจะล้มเหลวในกรณีที่คุณใช้กรอบการจัดการ bean ซึ่งใช้พร็อกซีเช่น CDI ใช้@PostConstruct
เพื่อเชื่อมต่อการเริ่มต้นอินสแตนซ์ bean ที่มีการจัดการเสมอ(และใช้@PreDestroy
เพื่อเชื่อมต่อกับการทำลายอินสแตนซ์ bean ที่มีการจัดการ) นอกจากนี้ในตัวสร้างคุณจะไม่สามารถเข้าถึงการอ้างอิงฉีดใด ๆ , See also NullPointerException ขณะที่พยายามจะเข้าถึง @Inject ถั่วในตัวสร้าง
ในกรณีที่entityId
จะถูกส่งผ่านทาง<f:viewParam>
ที่คุณจะต้องใช้แทน<f:viewAction>
@PostConstruct
ดูเพิ่มเติมเมื่อใช้ f: viewAction / preRenderView เทียบกับ PostConstruct?
คุณต้องตรวจสอบให้แน่ใจว่าคุณได้เก็บรักษาnull
โมเดลที่ไม่ใช่โมเดลไว้ในระหว่างการโพสต์แบ็คในกรณีที่คุณสร้างมันขึ้นมาด้วยadd()
วิธีการดำเนินการเท่านั้น ง่ายที่สุดคือใส่ถั่วในขอบเขตมุมมอง ดูวิธีการเลือกขอบเขตถั่วที่เหมาะสม
3. เป้าหมายไม่สามารถเข้าถึงได้ 'null' ส่งคืนค่าว่าง
สิ่งนี้มีสาเหตุเช่นเดียวกับ # 2 มีเพียงการใช้งาน EL (รุ่นเก่า) เท่านั้นที่ใช้งานได้ค่อนข้างติดขัดในการรักษาชื่อคุณสมบัติเพื่อแสดงในข้อความข้อยกเว้นซึ่งท้ายที่สุดจะแสดงเป็น 'null' อย่างไม่ถูกต้อง #{bean.entity.subentity.subsubentity.property}
นี้จะทำให้การแก้จุดบกพร่องและแก้ไขบิตยากเมื่อคุณได้ค่อนข้างบางคุณสมบัติที่ซ้อนกันชอบดังนั้น
วิธีแก้ปัญหายังคงเหมือนเดิม: ตรวจสอบให้แน่ใจว่าเอนทิตีที่ซ้อนกันเป็นปัญหาไม่ได้null
อยู่ในทุกระดับ
4. เป้าหมายไม่สามารถเข้าถึงได้ '' 0 '' ส่งคืนค่าว่าง
สิ่งนี้มีสาเหตุเช่นเดียวกับ # 2 เพียงการใช้งาน EL (รุ่นเก่า) ที่ใช้เท่านั้นที่มีข้อบกพร่องในการกำหนดข้อความข้อยกเว้น สิ่งนี้จะแสดงเฉพาะเมื่อคุณใช้เครื่องหมายวงเล็บปีกกา[]
ใน EL ใน#{bean.collection[index]}
กรณีที่#{bean.collection}
ตัวมันเองไม่เป็นโมฆะ แต่ไม่มีรายการในดัชนีที่ระบุ จากนั้นข้อความดังกล่าวจะต้องตีความว่า:
Target Unreachable, "collection [0]" ส่งคืนค่าว่าง
วิธีแก้ปัญหาก็เหมือนกับ # 2: ตรวจสอบให้แน่ใจว่ามีรายการคอลเลกชัน
5. Target Unreachable, 'BracketSuffix' ส่งคืนค่า null
นี้มีจริงสาเหตุเดียวกับ # 4 เท่านั้น (เก่า) การดำเนิน EL ถูกนำมาใช้ค่อนข้างรถในการรักษาดัชนีย้ำที่จะแสดงในข้อความแสดงข้อยกเว้นซึ่งในที่สุดสัมผัสไม่ถูกต้องเป็น 'BracketSuffix' ]
ซึ่งจริงๆตัวละคร สิ่งนี้ทำให้การดีบักและแก้ไขยากขึ้นเล็กน้อยเมื่อคุณมีหลายรายการในคอลเลกชัน
สาเหตุอื่น ๆ ที่เป็นไปได้ของjavax.el.PropertyNotFoundException
: