2011-07-22 63 views
2

我刚开始使用JSF,我不明白为什么我的服务没有注入到控制器中。尚未设置JSF 2.0 @ManagedProperty

@ManagedBean 
@ApplicationScoped 
public class MyController { 

    @ManagedProperty(value = "#{service}") 
    private MyService service; 

    public void setService(MyService service) { 
     this.service = service; 
    } 

    public MyService getService() { 
     return service; 
    } 

    public void callToService(AjaxBehaviorEvent event) { 
     System.out.println(service); 
    } 

} 

问:什么是在@ManagedProperty值的目的是什么?

@ManagedBean 
@ApplicationScoped 
public class MyService { 

} 

点击按钮调用方法callToService但服务null

<h:form> 
     <h:commandButton value="Call Service"> 
      <f:ajax listener="#{myController.callToService}"/> 
     </h:commandButton> 
</h:form> 

回答

4

#{service}实际上解析为null可能发生。

当您使用@ManagedBean没有name属性像你一样,托管bean名称将默认决心与小写1焦炭类名(至少符合JavaBeans规范),所以你MyService bean将有效地得到管理豆类名称myService

所以基本上有两种方法可以解决这个问题,

  1. 使用#{myService}代替。

    @ManagedProperty("#{myService}") 
    private MyService service; 
    
  2. 指定托管bean自己的名字,使之成为可作为#{service}

    @ManagedBean(name="service") 
    @ApplicationScoped 
    public class MyService { 
    
    } 
    

无关到具体的问题,因为你似乎不感兴趣的AJAX事件,而是在行动时,那么你也可以简化使用的<f:ajax>如下:

<h:commandButton value="Call Service" action="#{myController.callToService}"> 
    <f:ajax /> 
</h:commandButton> 

public void callToService() { 
    System.out.println(service); 
} 

,这样当最终用户没有启用JS时它仍然可以工作。

最后,业务服务通常设计为@Stateless EJB,而不是JSF托管bean,因为它应该与JSF视图没有直接关系。你可以使用

@EJB 
private MyService service; 
+0

我按照你的建议使用'@ EJB',但它不工作。我想我需要改变'MyService'的注释,因为它不再是一个托管bean。 – Sydney

+0

是的,使用'@ Stateless'。请注意,您需要一个支持EJB的servletcontainer,例如Glassfish,JBoss等。 – BalusC

+0

我使用的是Tomcat 6,但我在使用maven的类路径中添加了'openejb'。只是为了确保,'MyService'只需要'@ Stateless'?因为我得到这个异常:引起:javax.naming.NameNotFoundException:名称com.xxxxxxxx.controller.MyController未绑定在此上下文中 – Sydney

相关问题