无法实例化JSF 2受管Bean [英] JSF 2 managed bean does not get instantiated
问题描述
我在创建的这个示例jsf项目中遇到了这个问题.托管bean不会实例化. Bean类:
I am having this problem in this sample jsf project I created. Managed beans do not get instantiated. Bean class:
@ManagedBean(name="loginMB")
@RequestScoped
public class LoginMB extends AbstractMB {
private static final long serialVersionUID = -8523135776442886000L;
@ManagedProperty("#{userMB}")
private UserMB userMB;
//getters and setters
public String login() {
UserSupport userSupport = new UserSupportImpl();
User user = userSupport.isValidLogin(email, password);
if (user != null) {
getUserMB().setUser(user);
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
request.getSession().setAttribute("user", user);
return "loggedIn";
//return "/pages/protected/index.xhtml";
}
displayErrorMessageToUser("Check your email/password");
return null;
}
}
ManagedBean批注和RequestScope批注已从
ManagedBean annotation and RequestScope annotation have been imported from
导入javax.faces.bean.*;
import javax.faces.bean.*;
这就是我在bean上面使用过的方式,
this is how i ve used above bean,
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<p>#{bundle.loginHello}</p>
<h:form>
<p:growl showDetail="false" life="3000" />
<h:panelGrid columns="2">
<h:outputLabel value="#{bundle.loginUserName}" />
<h:inputText value="#{loginMB.email}" label="Email" id="email" required="true">
<f:validateLength minimum="6" />
</h:inputText>
<h:outputLabel value="#{bundle.loginPassword}" />
<h:inputSecret value="#{loginMB.password}" label="Password" id="senha" required="true" autocomplete="off" >
<f:validateLength minimum="6" />
</h:inputSecret>
</h:panelGrid>
<p:commandButton action="#{loginMB.login}" value="Log in" ajax="false" />
</h:form>
</h:body>
</html>
其他托管bean
@SessionScoped
@ManagedBean(name = "userMB")
public class UserMB implements Serializable {
public static final String INJECTION_NAME = "#{userMB}";
private static final long serialVersionUID = 1L;
private User user;
.......
}
例外:
javax.el.PropertyNotFoundException: /login.xhtml @14,83 value="#{loginMB.email}": Target Unreachable, identifier 'loginMB' resolved to null
at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)
faces-config.xml
faces-config.xml
<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_1.xsd"
version="2.1">
<application>
<resource-bundle>
<base-name>messages</base-name>
<var>bundle</var>
</resource-bundle>
<message-bundle>messages</message-bundle>
</application>
<navigation-rule>
<from-view-id>/login.xhtml</from-view-id>
<navigation-case>
<from-action>#{loginMB.login}</from-action>
<from-outcome>loggedIn</from-outcome>
<to-view-id>/index.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<!-- <managed-bean>
<managed-bean-name>loginMB</managed-bean-name>
<managed-bean-class> com.sample.jsfjpa.beans.LoginMB</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>userMB</managed-bean-name>
<managed-bean-class> com.sample.jsfjpa.beans.UserMB</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean> -->
</faces-config>
推荐答案
除非您专门调用它们的属性或方法之一,否则不会创建托管bean.对于所有作用域,除了在加载JSF上下文时专门创建的具有@ManagedBean(eager=true)
的@ApplicationScoped
以外,所有情况都将发生这种情况.
Managed beans are not created unless you specifically invoke one of their properties or methods. That happens for all the scopes, except the @ApplicationScoped
ones having @ManagedBean(eager=true)
which are specifically created when JSF context loads.
这里您是从视图中引用#{loginMB}
,而不是#{userMB}
,因此没有机会创建它.
Here you're referencing #{loginMB}
from the view, but not #{userMB}
so there's no chance to have it created.
为了实例化@SessionScoped
托管Bean,可以在登录页面中添加以下代码:
In order to instance your @SessionScoped
managed bean you can add following code in your login page:
<f:metadata>
<f:event type="preRenderView" listener="#{userMB.initialize}" />
</f:metadata>
在页面渲染之前,设置监听器.您可以在这里仅调用一个空方法(要执行该方法,如果尚未创建,则JSF会构造您的bean).
Which sets a listener that is executed before page rendering. You can invoke here just an empty method (to execute it JSF will construct your bean if not already created).
从JSF 2.2开始,您可以将preRenderView
方法替换为新的f:viewAction
,它具有一些优点(它是无参数的,并且不会在回发时调用):
Starting from JSF 2.2 you can replace the preRenderView
method for the new f:viewAction
, which has some benefits (it's parameterless and it doesn't get invoked on postbacks ):
<f:metadata>
<f:viewAction action="#{userMB.initialize}" />
</f:metadata>
这篇关于无法实例化JSF 2受管Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!