当试图引用el中的托管bean时 #{bean.entity.property}
,有时是 javax.el.PropertyNotFoundException: Target Unreachable
通常在设置bean属性或调用bean操作时抛出异常。
似乎有五种不同的信息:
目标不可访问,标识符“bean”解析为空
无法访问目标,“实体”返回null
无法访问目标,“null”返回null
无法访问目标,“0”返回null
无法访问目标,“bracketsuffix”返回null
它们都是什么意思?它们是如何产生的,应该如何解决?
1条答案
按热度按时间f45qwnt81#
1. 目标不可访问,标识符“bean”解析为空
这可以归结为,在el中,托管bean示例本身不能被该标识符(托管bean名称)准确地找到
#{bean}
.确定原因可分为三个步骤:
答。谁在管理豆子?
b。托管bean的(默认)名称是什么?
c。支持bean类在哪里?
第1a条。谁在管理豆子?
第一步是检查哪个bean管理框架负责管理bean示例。是cdi via吗
@Named
? 还是jsf via@ManagedBean
? 还是Spring@Component
? 您能确保在同一个backingbean类上没有混合多个bean管理框架特定的注解吗?例如@Named @ManagedBean
,@Named @Component
,或@ManagedBean @Component
. 这是错误的。bean最多只能由一个bean管理框架管理,并且必须正确配置该框架。如果您已经不知道要选择哪一个,那么请转到backingbean(@managedbean)或cdibean(@named)?以及springjsf集成:如何在jsf管理的bean中注入spring组件/服务?万一是cdi通过
@Named
,则需要确保以下各项:CDI1.0(JavaEE6)需要
/WEB-INF/beans.xml
文件,以便在战争中启用cdi。它可以为空,也可以只有以下内容:cdi 1.1(java ee 7)没有任何
beans.xml
,或一个空的beans.xml
文件,或与上述cdi 1.0兼容beans.xml
将与cdi 1.0的行为相同。当CDI1.1兼容时beans.xml
有明确的version="1.1"
,则默认情况下它将只注册@Named
带有显式cdi范围注解的bean,例如@RequestScoped
,@ViewScoped
,@SessionScoped
,@ApplicationScoped
如果您打算将所有bean注册为cdi管理的bean,即使是没有显式cdi作用域的bean,也可以使用下面的cdi1.1/WEB-INF/beans.xml
与bean-discovery-mode="all"
设置(默认值为bean-discovery-mode="annotated"
).使用cdi 1.1+时
bean-discovery-mode="annotated"
(默认),确保没有意外地导入jsf范围,例如javax.faces.bean.RequestScoped
而不是cdi范围javax.enterprise.context.RequestScoped
. 注意ide自动完成。使用mojarra 2.3.0-2.3.2和cdi 1.1+时
bean-discovery-mode="annotated"
(默认),然后由于一个bug,您需要将mojarra升级到2.3.3或更新版本。如果无法升级,则需要设置bean-discovery-mode="all"
在beans.xml
,或者将JSF2.3@FacesConfig
war中任意类上的注解(通常是某种应用程序范围的启动类)。在Servlet4.0容器上使用JSF2.3时
web.xml
声明符合Servlet4.0,那么您需要显式地将JSF2.3@FacesConfig
war中任意类上的注解(通常是某种应用程序范围的启动类)。这在Servlet3.x中不是必需的。像tomcat和jetty这样的非javaee容器并不附带cdi。你需要手动安装。这比仅仅添加库jar要多一些工作。对于tomcat,请确保遵循以下答案中的说明:如何在tomcat上安装和使用cdi?
运行时类路径是干净的,在cdiapi相关jar中没有重复项。确保您没有混合使用多个cdi实现(weld、openwebbeans等)。当目标容器已经打包了cdiapi时,确保不要在webapp中提供另一个cdi甚至javaeeapi jar文件。
如果要将用于jsf视图的cdi托管bean打包到jar中,那么请确保jar至少有一个有效的
/META-INF/beans.xml
(可以保持为空)。如果是jsf通过since 2.3管理bean的话
@ManagedBean
,并且您不能迁移到cdi,那么您需要确保:这个
faces-config.xml
根声明与jsf2.0兼容。所以xsd文件和version
必须至少指定JSF2.0或更高版本,因此不能指定1.x。对于jsf2.1,只需替换
2_0
以及2.0
由2_1
以及2.1
分别。如果您使用的是jsf2.2或更高版本,那么请确保您使用的是
xmlns.jcp.org
名称空间而不是java.sun.com
到处都是。对于jsf2.3,只需替换
2_2
以及2.2
由2_3
以及2.3
分别。你不是偶然导入的
javax.annotation.ManagedBean
而不是javax.faces.bean.ManagedBean
. 注意ide的autocomplete,众所周知eclipse会自动将错误的提示作为列表中的第一项。你没有覆盖
@ManagedBean
通过jsf1.x风格<managed-bean>
进入faces-config.xml
在同一个backingbean类上使用不同的托管bean名称。这个优先于@ManagedBean
. 在中注册托管beanfaces-config.xml
从JSF2.0开始就没有必要了,只要删除它就行了。运行时类路径是干净的,在jsfapi相关jar中没有重复项。确保您没有混合使用多个jsf实现(mojarra和myfaces)。当目标容器已经打包了jsfapi时,确保不要在webapp中提供另一个jsf甚至javaeeapi jar文件。另请参阅jsfwiki页面的“安装jsf”部分,以获取jsf安装说明。如果您打算从war-on而不是容器本身升级容器绑定的jsf,请确保已指示目标容器使用war绑定的jsfapi/impl。
如果要将jsf管理的bean打包到jar中,那么请确保jar至少有一个与jsf2.0兼容的bean
/META-INF/faces-config.xml
. 另请参阅如何引用jar文件中提供的jsf托管bean?如果您实际使用的是jurassic jsf1.x,并且无法升级,那么您需要通过
<managed-bean>
在faces-config.xml
而不是@ManagedBean
. 不要忘记修复项目构建路径,这样您就不再有JSF2.x库了(这样@ManagedBean
注解不会令人困惑地成功编译)。以防是spring通过
@Component
,则需要确保以下各项:spring正在按照其文档进行安装和集成。重要的是,你至少要把这个放进去
web.xml
:还有这个
faces-config.xml
:(以上是我所知道的关于spring的所有信息-我不做spring-请随意编辑/评论其他可能与spring相关的原因;e、 g.一些与xml配置相关的问题)
如果是中继器组件通过其
var
属性(例如。<h:dataTable var="item">
,<ui:repeat var="item">
,<p:tabView var="item">
,等等)并且您实际得到了“target unreachable,identifier'item'resolved to null”,那么您需要确保:这个
#{item}
中未引用binding
任何子组件的属性。这是不正确的,因为binding
属性在视图生成时运行,而不是在视图渲染时运行。此外,在组件树中只有一个组件,在每一轮迭代中都可以简单地重用。换句话说,你实际上应该使用binding="#{bean.component}"
而不是binding="#{item.component}"
. 但是更好的方法是完全摆脱组件bining到bean,并调查/询问您认为用这种方法解决的问题的正确方法。另请参见“binding”属性在jsf中是如何工作的?何时以及如何使用?第1b条。托管bean的(默认)名称是什么?
第二步是检查已注册的托管bean名称。jsf和spring使用约定符合javabeans规范,而cdi根据cdi impl/version有例外。
一
FooBean
像下面这样支持bean类,在所有bean管理框架中,默认的托管bean名称是
#{fooBean}
,符合javabeans规范。一
FOOBean
像下面这样支持bean类,它的非限定类名至少以两个大写字母开头,在jsf和spring中会有一个与非限定类名完全相同的默认托管bean名称
#{FOOBean}
,也符合javabeans规范。在cdi中,在2015年6月之前发布的焊接版本中也是如此,但在2015年6月之后发布的焊接版本(2.2.14/2.3.0.b1/3.0.0.a9)中,由于cdi规范中的疏忽,openwebbeans中也没有这种情况。在这些焊接版本和所有owb版本中,只有第一个字符小写#{fOOBean}
.如果已显式指定托管bean名称
foo
如下图所示,或等同于
@ManagedBean(name="foo")
或者@Component("foo")
,则只能在#{foo}
因此不是通过#{fooBean}
.1摄氏度。支持bean类在哪里?
第三步是双重检查backingbean类是否在构建和部署的war文件中的正确位置。确保您已经正确地执行了项目和服务器的完全清理、重建、重新部署和重新启动,以防您实际上正忙于编写代码并不耐烦地在浏览器中按f5。如果仍然是徒劳的,让构建系统生成一个war文件,然后用zip工具对其进行提取和检查。汇编的
.class
备份bean类的文件必须驻留在其包结构中/WEB-INF/classes
. 或者,当它被打包为jar模块的一部分时,包含已编译.class
文件必须位于/WEB-INF/lib
而不是耳朵/lib
或者其他地方。如果您使用的是eclipse,请确保backingbean类位于
src
因此不是WebContent
,并确保已启用“项目>自动生成”。如果您使用的是maven,请确保backingbean类在src/main/java
因此不在*