1. Ulaşılamaz hedef, tanımlayıcı "bean" boş olarak çözüldü
Bu, yönetilen fasulye örneğinin kendisinin EL'de tam olarak bu tanımlayıcı (yönetilen fasulye adı) tarafından bulunamamasıyla sonuçlanır. #{bean}
.
Nedeni belirlemek üç adıma ayrılabilir:
a. Fasulyeyi kim yönetiyor?
b. (Varsayılan) yönetilen fasulye adı nedir?
c. Destekleyici fasulye sınıfı nerede?
1 A. Fasulyeyi kim yönetiyor?
İlk adım, fasulye örneğini yönetmekten hangi fasulye yönetim çerçevesinin sorumlu olduğunu kontrol etmek olacaktır. Öyle mi JSF aracılığıyla @ManagedBean
? Yoksa CDI yoluyla @Named
mı? Ya öyle Bahar aracılığıyla@Component
mı? Aynı destekleyici fasulye sınıfında birden fazla fasulye yönetimi çerçevesine özgü ek açıklamayı karıştırmadığınızdan emin olabilir misiniz? Örneğin @Named @Component
, veya @Named @ManagedBean
, veya @ManagedBean @Component
. Bu yanlış. Çekirdek en fazla bir çekirdek yönetim çerçevesi tarafından yönetilmeli ve bu çerçeve uygun şekilde yapılandırılmalıdır. Hangisini seçeceğiniz konusunda zaten bir fikriniz yoksa, Backingbean'lara (@ManagedBean) veya CDI Beans'e (@Named) gidin? ve Spring JSF entegrasyonu: JSF tarafından yönetilen çekirdeğe bir Spring bileşeni / hizmeti nasıl enjekte edilir?
Durumda bulunuyor JSF aracılığıyla fasulye yönettiğini @ManagedBean
, o zaman emin aşağıdakilerden yapmak gerekir:
faces-config.xml
Kök beyanı JSF 2.0 ile uyumludur. Yani XSD dosyası ve version
zorunluluk en az JSF 2.0 veya daha yüksek ve dolayısıyla değil 1.x belirtmek
<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 için, 2_0
ve 2.0
ile 2_1
ve 2.1
sırasıyla.
JSF 2.2 veya üzerindeyseniz, kullandığınızdan emin olun. xmlns.jcp.org
java.sun.com
üzerindeyseniz, her yerde yerine ad alanları .
<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 için, değiştirin 2_2
ve2.2
ile 2_3
ve 2.3
sırasıyla.
Yanlışlıkla içe aktarmadınız javax.annotation.ManagedBean
yerine aktarmadınızjavax.faces.bean.ManagedBean
. IDE otomatik tamamlama ile dikkat edin, Eclipse'in listedeki ilk öğe olarak yanlış olanı otomatik olarak önerdiği bilinmektedir.
- İçinde
@ManagedBean
JSF 1.x stili <managed-bean>
girişi geçersiz kılmadınızfaces-config.xml
Aynı destek fasulye sınıfında farklı bir yönetilen fasulye adıyla birlikte . Bu bir önceliğe sahip olacak @ManagedBean
. faces-config.xml
JSF 2.0'dan beri yönetilen bir bean'i kaydetmek gerekli değildir, onu kaldırmanız yeterlidir.
- Çalışma zamanı sınıf yolunuz temizdir ve JSF API ile ilgili JAR'larda kopyalar içermez. Birden çok JSF uygulamasını (Mojarra ve MyFaces) karıştırmadığınızdan emin olun. Hedef kapsayıcı zaten JSF API'yi kutudan çıkardığında web uygulaması boyunca başka bir JSF veya hatta Java EE API JAR dosyası sağlamadığınızdan emin olun. Ayrıca JSF wiki sayfamızın "JSF'yi Yükleme" bölümüne bakın.JSF kurulum talimatları için JSF . Konteynerle paketlenmiş JSF'yi konteynerin kendisi yerine WAR'dan yükseltmeyi planlıyorsanız, hedef konteynere WAR ile paketlenmiş JSF API / impl kullanma talimatı verdiğinizden emin olun.
- JSF tarafından yönetilen çekirdekleri bir JAR'da paketliyorsanız, JAR'ın en az JSF 2.0 uyumlu olduğundan emin olun.
/META-INF/faces-config.xml
. Ayrıca bkz . Bir JAR dosyasında sağlanan JSF tarafından yönetilen çekirdeklere nasıl başvurulur?
Eğer ediyorsanız aslında jurassic JSF 1.x kullanılarak ve Yükseltemiyorsanız, o zaman aracılığıyla fasulye kaydetmeniz gerekir <managed-bean>
içinde faces-config.xml
yerine @ManagedBean
. Artık JSF 2.x kitaplıklarınız olmayacak şekilde proje oluşturma yolunuzu düzeltmeyi unutmayın (böylece @ManagedBean
ek açıklama kafa karıştırıcı bir şekilde başarılı bir şekilde derlenmesin).
Durumda bulunuyor CDI aracılığı fasulye yönettiğini @Named
, o zaman emin aşağıdakilerden yapmak gerekir:
CDI 1.0 (Java EE 6), /WEB-INF/beans.xml
WAR'da CDI'yı etkinleştirmek için bir dosya gerektirir . Boş olabilir veya yalnızca aşağıdaki içeriğe sahip olabilir:
<?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>
Herhangi bir beans.xml
veya boş bir beans.xml
dosya olmadan veya yukarıdaki CDI 1.0 uyumlu CDI 1.1 (Java EE 7) , CDI 1.0 beans.xml
ile aynı şekilde davranacaktır. Bir CDI 1.1 uyumlu olmadığı zaman beans.xml
açık olarak version="1.1"
, o zaman varsayılan olarak yalnızca kaydeder @Named
fasulye ile gibi açık bir CDI kapsamı açıklama @RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
, vb Eğer hatta açık bir olmadan, CDI fasulye yönetilen gibi tüm fasulye kayıt niyetinde CDI kapsamı, CDI uyumlu 1.1 altında kullanmak /WEB-INF/beans.xml
ile bean-discovery-mode="all"
(varsayılan kümesi 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>
bean-discovery-mode="annotated"
(Varsayılan) ile CDI 1.1+ kullanırken , yanlışlıkla bir JSF kapsamını içe aktarmadığınızdan emin olun.javax.faces.bean.RequestScoped
kullanırken, bir CDI kapsamı yerinejavax.enterprise.context.RequestScoped
. IDE otomatik tamamlama ile dikkat edin.
- Mojarra 2.3.0-2.3.2 ve CDI 1.1+
bean-discovery-mode="annotated"
(varsayılan) ile kullanıldığında, bir hata nedeniyle Mojarra'yı 2.3.3 veya daha yenisine yükseltmeniz gerekir . Yükseltemiyorsanız, ikisinden birini ayarlamanız gerekir bean-discovery-mode="all"
.beans.xml
veya MTU 2.3 belirli koymak için @FacesConfig
(genellikle bir uygulamanın bir çeşit başlangıç sınıfı kapsamlı) WAR keyfi sınıfına ek açıklama.
- Tomcat ve Jetty gibi Java dışı EE kapsayıcıları CDI paketiyle birlikte gönderilmez. Manuel olarak kurmanız gerekir. Kitaplık JAR (lar) ını eklemekten biraz daha fazla iş. Tomcat için, şu yanıtta verilen talimatları izlediğinizden emin olun: Tomcat'e CDI nasıl kurulur ve kullanılır?
- Çalışma zamanı sınıf yolunuz temizdir ve CDI API ile ilgili JAR'larda kopya içermez. Birden fazla CDI uygulamasını (Weld, OpenWebBeans, vb.) Karıştırmadığınızdan emin olun. Hedef kapsayıcı zaten CDI API'sini kutudan paketlediğinde web uygulaması boyunca başka bir CDI veya hatta Java EE API JAR dosyası sağlamadığınızdan emin olun.
Bir JAR'da JSF görünümleri için CDI tarafından yönetilen çekirdekleri paketliyorsanız, JAR'da en az bir geçerli /META-INF/beans.xml
(boş tutulabilir) olduğundan emin olun .
Fasulyeyi yönetenin Bahar olması durumunda @Component
, aşağıdakilerden emin olmanız gerekir:
Yay, dokümantasyonuna göre kurulmakta ve entegre edilmektedir . Daha da önemlisi, en azından şunlara sahip olmanız gerekir web.xml
:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Ve bu da faces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(Bahar ile ilgili bildiğim her şey yukarıda - Bahar yapmıyorum - diğer olası Bahar ile ilgili nedenleri düzenlemek / yorum yapmaktan çekinmeyin; örneğin, XML yapılandırmasıyla ilgili bazı sorunlar)
Durumda bir var tekrarlayıcı bileşeni onun aracılığıyla (iç içe) fasulye yönettiğini var
(örn özniteliği <h:dataTable var="item">
, <ui:repeat var="item">
, <p:tabView var="item">
, vs) ve aslında var bir "Hedef ulaşılamaz, tanımlayıcı 'madde' null çözülmesi", o zaman aşağıdakilerden emin olmak gerekir :
#{item}
Başvuruda bulunulan binding
herhangi bir çocuk bileşeninin attribtue. Bu, binding
öznitelik görünüm oluşturma sırasında değil, görünüm oluşturma zamanında çalıştığından yanlıştır . Dahası, bileşen ağacında fiziksel olarak her yineleme turunda basitçe yeniden kullanılan tek bir bileşen vardır. Başka bir deyişle, aslında binding="#{bean.component}"
yerine kullanmalısınız binding="#{item.component}"
. Ancak çok daha iyisi, bileşen gruplamadan tamamen kurtulmak ve bu şekilde çözmeyi düşündüğünüz problem için uygun yaklaşımı araştırmak / sormaktır. Ayrıca bkz . 'Bağlama' özelliği JSF'de nasıl çalışır? Ne zaman ve nasıl kullanılmalıdır?
1b. (Varsayılan) yönetilen fasulye adı nedir?
İkinci adım, kayıtlı yönetilen fasulye adının kontrol edilmesidir. JSF ve Spring kullanım kuralları JavaBeans şartnamesine uygundur , CDI ise CDI impl / versiyonuna bağlı istisnalara sahiptir.
FooBean
Aşağıdaki gibi bir destek fasulye sınıfı,
@Named
public class FooBean {}
tüm fasulye yönetim çerçevelerinde, #{fooBean}
JavaBeans spesifikasyonuna göre varsayılan bir yönetilen fasulye adı olacaktır .
FOOBean
Aşağıdaki gibi bir destek fasulye sınıfı,
@Named
public class FOOBean {}
Niteliksiz sınıf adı en az iki büyük harfle başlayan JSF ve Spring'de, tam olarak nitelenmemiş sınıf adına sahip varsayılan bir yönetilen fasulye adı olacaktır #{FOOBean}
, ayrıca JavaBeans belirtimine uygundur. CDI'da, Haziran 2015'ten önce yayınlanan Weld sürümlerinde de durum söz konusudur, ancak Haziran 2015'ten sonra yayınlanan Weld sürümlerinde (2.2.14 / 2.3.0.B1 / 3.0.0.A9) veya bir gözetim nedeniyle OpenWebBeans'te CDI özellikleri . Bu Weld sürümlerinde ve tüm OWB sürümlerinde, yalnızca ilk karakter küçük harflidir #{fOOBean}
.
Aşağıdaki gibi açıkça bir yönetilen fasulye adı belirlediyseniz foo
,
@Named("foo")
public class FooBean {}
veya eşdeğer ile @ManagedBean(name="foo")
veya @Component("foo")
, o zaman sadece kadar ulaşılabilir #{foo}
ve böylece değil tarafından #{fooBean}
.
1c. Destekleyici fasulye sınıfı nerede?
Üçüncü adım, destekleyici fasulye sınıfının oluşturulan ve konuşlandırılan WAR dosyasında doğru yerde olup olmadığını iki kez kontrol etmek olacaktır. Gerçekten kod yazmakla meşgul olmanız ve tarayıcıda sabırsızlıkla F5'e basmanız durumunda proje ve sunucuyu tam olarak temizlediğinizden, yeniden oluşturduğunuzdan, yeniden konuşlandırdığınızdan ve yeniden başlattığınızdan emin olun. Hala boşuna kalırsanız, derleme sisteminin daha sonra bir ZIP aracıyla çıkarıp inceleyeceğiniz bir WAR dosyası oluşturmasına izin verin. .class
Destek fasulye sınıfının derlenmiş dosyası, içindeki paket yapısında bulunmalıdır /WEB-INF/classes
. Veya, bir JAR modülünün parçası olarak paketlendiğinde, derlenen .class
dosyayı içeren JAR, içinde bulunmalıdır /WEB-INF/lib
ve dolayısıyla örneğin EAR'lar /lib
veya başka bir yerde olmamalıdır .
Eclipse kullanıyorsanız, destekleyici fasulye sınıfının içinde olduğundan src
ve öyle olmadığından WebContent
emin olun ve Proje> Otomatik Olarak Oluştur'un etkinleştirildiğinden emin olun . Maven kullanıyorsanız, destek fasulye sınıf içinde olduğundan emin olmak src/main/java
dolayısıyla ve değil de src/main/resources
ya src/main/webapp
.
Web uygulamasını EJB + WAR (lar) ile bir EAR'nin parçası olarak paketliyorsanız, destekleyici fasulye sınıflarının WAR modülünde olduğundan ve dolayısıyla EAR modülünde veya EJB modülünde olmadığından emin olmanız gerekir. İşletme katmanı (EJB), web katmanı (WAR) ile ilgili herhangi bir yapı içermemelidir, böylece işletme katmanı birden çok farklı web katmanında (JSF, JAX-RS, JSP / Servlet, vb.) Yeniden kullanılabilir.
2. Ulaşılamayan Hedef, "varlık" null döndürdü
Bu , döndüğü gibi yuvalanmış özelliğe indirgenir . Bu genellikle yalnızca JSF'nin aşağıdaki gibi bir girdi bileşeni aracılığıyla değeri ayarlaması gerektiğinde ortaya çıkar , ancak gerçekte döndürülür .entity
#{bean.entity.property}
null
property
#{bean.entity}
null
<h:inputText value="#{bean.entity.property}" />
CRUD listeleri ve / veya aynı görünümde diyaloglarla çalışmanız durumunda , model varlığını bir @PostConstruct
, veya <f:viewAction>
yöntemde veya belki bir add()
eylem yönteminde önceden hazırladığınızdan emin olmanız gerekir .
@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();
}
// ...
}
Önemine gelince @PostConstruct
; CDI gibi proxy'ler kullanan bir fasulye yönetimi çerçevesi kullanıyorsanız bunu normal bir kurucuda yapmak başarısız olur . Her zaman @PostConstruct
, yönetilen bean örneği başlatmaya bağlanmak için kullanın (ve @PreDestroy
yönetilen bean örneği yıkımına bağlanmak için kullanın). Ek olarak, bir yapıcıda henüz enjekte edilen bağımlılıklara erişiminiz olmazdı, ayrıca yapıcıda @Inject bean'e erişmeye çalışırken NullPointerException'a bakın .
Durumda entityId
yoluyla beslenir <f:viewParam>
, kullanmak ihtiyacım olacağını <f:viewAction>
yerine @PostConstruct
. Ayrıca bkz. F: viewAction / preRenderView ve PostConstruct ne zaman kullanılır?
Ayrıca, null
modeli yalnızca bir add()
eylem yönteminde oluşturuyorsanız, geri göndermeler sırasında modeli koruduğunuzdan da emin olmanız gerekir . En kolayı fasulyeyi görüş alanına koymaktır. Ayrıca bkz . Doğru fasulye kapsamı nasıl seçilir?
3. Ulaşılamayan Hedef, 'null' null döndürdü
Bu aslında # 2 ile aynı nedene sahiptir, sadece (daha eski) EL uygulaması, istisna mesajında görüntülenecek özellik adının korunmasında biraz hatalı ve sonuçta yanlış olarak 'boş' olarak ortaya çıkar. Bu, yalnızca bunun gibi iç içe geçmiş özellikler oldukça olduğunda hata ayıklamayı ve düzeltmeyi biraz daha zor hale getirir #{bean.entity.subentity.subsubentity.property}
.
Çözüm hala aynı: söz konusu iç içe geçmiş varlığın null
tüm düzeylerde olmadığından emin olun .
4. Hedef Ulaşılamıyor, "0" null döndürdü
Bu aynı zamanda # 2 ile aynı nedene sahiptir, sadece kullanılan (daha eski) EL uygulaması, istisna mesajını formüle etmede hatalıdır. Eğer ayracı gösterim kullandığınızda bu İFŞA sadece []
olduğu gibi EL #{bean.collection[index]}
nereye #{bean.collection}
kendisi boş olmayan, ancak belirtilen dizindeki öğe yok. Böyle bir mesaj daha sonra şu şekilde yorumlanmalıdır:
Ulaşılamayan Hedef, "koleksiyon [0]" null döndürdü
Çözüm ayrıca 2 numaralı ile aynıdır: koleksiyon öğesinin mevcut olduğundan emin olun.
5. Hedef Ulaşılamıyor, 'BracketSuffix' boş döndürdü
Bu aslında # 4 ile aynı nedene sahiptir, sadece (daha eski) EL uygulaması, istisna mesajında görüntülenecek yineleme indeksini korumada biraz hatalı ve sonuçta yanlış bir şekilde gerçekten karakter olan 'BracketSuffix' olarak ortaya çıkar ]
. Bu, yalnızca koleksiyonda birden çok öğe olduğunda hata ayıklamayı ve düzeltmeyi biraz daha zor hale getirir.
Diğer olası nedenler javax.el.PropertyNotFoundException
: