2014-11-24 32 views
0

當我想在我的XHTML下面的代碼來訪問我的管理bean的登錄方法:JSF:在調用managedbean捐贈異常的方法

<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,因爲我想調用我的方法。如果這是不可能的,我應該選擇什麼方法。

+1

發佈完整的堆棧跟蹤。另外你想用你的bean什麼,你想讓它由Spring或JSF管理。此刻你有兩個會導致奇怪的錯誤。 – 2014-11-24 06:03:58

回答

1

感謝wittakarn花時間來回答這個問題,但它部分地回答了這個問題。我研究了這個主題,並發現了一篇非常好的文章here

我們不能在JSF託管bean中使用@Autowired來注入spring bean,因爲JSF bean是可序列化的,而Spring bean並非如此。 @wittakarn採取的方法很好,除了有一個問題。在loginService的setter中,我必須創建一個新的loginService對象,並給它引用「this」類,其中所有鬆散耦合的概念都打破了!

相反,有一個好方法。 Spring希望它的bean是非可加密的。所以首先我們必須使loginService成爲非序列化屬性,然後在init方法中調用externalContext,並將自動裝配的功能賦予「this」類。代碼看起來像這樣:

@Autowired 
    transient LoginService loginServiceImpl; 
    @PostConstruct 
    private void init() { 
     ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
     ServletContext servletContext = (ServletContext) externalContext.getContext(); 
     WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext). 
     getAutowireCapableBeanFactory(). 
     autowireBean(this); 
    } 

並猜測什麼!它的工作:)