2011-07-22 61 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

相關問題