当我尝试通过以下xhtml中的代码访问托管bean的登录方法时:
<p:commandButton value="Login" update="growl"
actionListener="#{loginView.login}"/>
我的LoginView类看起来像这样:
@Component
@ManagedBean(name="loginView",eager=true)
@SessionScoped
public class LoginView {
@Autowired
LoginService loginServiceImpl;
Student student=loginServiceImpl.login(username, password);
public void login(ActionEvent event) {
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage message = null;
boolean loggedIn = false;
if(username != null && student!=null && password != null ) {
loggedIn=True;
try {
FacesContext.getCurrentInstance()
.getExternalContext()
.redirect(location);
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我打电话按下按钮时,它给出了以下错误:
javax.el.ELException: /login1.xhtml @105,62 actionListener="#{loginView.login}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:147)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:818)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.primefaces.showcase.view.menu.LoginView.login(LoginView.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
... 26 more
奇怪的是,当我评论这条线时
Student student=loginServiceImpl.login(username, password);
代码运行正常。我希望我的bean都是两个,基于Spring,因为我想要自动装载loginServiceImpl和jsf,因为我想调用我的方法。如果不可能,我应该选择什么方法。
答案 0 :(得分:1)
您不能通过在JSF托管bean中使用@Autowired
来注入Spring bean。
你应该改为
@ManagedProperty(value="#{something}")
private LoginService loginServiceImpl; // getter and setter.
另见: Null pointer when autowiring the bean into JSF Managed bean
答案 1 :(得分:1)
感谢wittakarn花时间回答这个问题,但它部分地回答了这个问题。我研究了这个主题,并在同一here
上发现了一篇非常好的文章我们无法在JSF托管bean中使用@Autowired注入spring bean,因为JSF bean是可序列化的,而Spring bean则不是这样。 @wittakarn采取的方法很好,除了有一个问题。在loginService的setter中,我必须创建一个新的loginService对象并给它引用&#34;这个&#34;类,松耦合的所有概念都破了!
相反,有一个好方法。 Spring希望它的bean不可连接。因此,首先我们必须使loginService成为一个非序列化的属性,使其成为瞬态,然后在init方法中调用externalContext并将自动装配的功能赋予&#34;这个&#34;类。代码如下所示:@Autowired
transient LoginService loginServiceImpl;
@PostConstruct
private void init() {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
ServletContext servletContext = (ServletContext) externalContext.getContext();
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).
getAutowireCapableBeanFactory().
autowireBean(this);
}
猜猜是什么!!它正在工作:)