2014-11-24 53 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); 
    } 

并猜测什么!它的工作:)