2013-03-16 29 views
5

我已經創建了JAX-RS服務,我想在其中注入一個應用程序作用域bean。問題是這個bean沒有被注入。這是如何造成的,我該如何解決這個問題?無法在JAX-RS服務中注入@ApplicationScoped bean

JAX-RS服務:

@Path("room") 
public class RoomService { 

    @Inject 
    GameController gc; 

    public RoomService() {} 

    @Path("create") 
    @GET 
    @Produces("application/json") 
    public String create() { 
     Room r = new Room(); 
     gc.addRoom(r); // gc is null 
     return r.toJson(); 
    } 
} 

應用範圍的bean

import java.util.ArrayList; 
import javax.enterprise.context.ApplicationScoped; 
import javax.inject.Named; 
import pepuch.multuplayergameserver.entity.Game; 
import pepuch.multuplayergameserver.entity.Room; 

@Named 
@ApplicationScoped 
public class GameController { 

    private Game game; 

    public GameController() { 
     this.game = new Game(new ArrayList<Room>()); 
    } 

    public boolean addRoom(Room room) { 
     if (!game.getRooms().contains(room)) { 
      return game.getRooms().add(room); 
     } 

     return false; 
    } 

} 
+0

您的'GameController'代碼不能編譯,也缺少'@ Named'。請不要寫下未經測試的代碼。改爲複製真實且經過測試的代碼。 – BalusC 2013-03-16 19:02:18

+2

我修復了它。抱歉。我添加了@ @命名,但它仍然不起作用。我雖然'@ Named'只用於'EL',這就是爲什麼我沒有添加這個之前。 – pepuch 2013-03-16 19:23:06

+2

爲什麼@Named?不會有任何區別。 – 2013-03-17 15:47:50

回答

5

你需要做的豆腐託管資源,使之符合注入。在最低限度上,將@RequestScoped添加到JAX-RS SIB以使其具有注入價值。

另一個備選註釋是@ManagedBean。問題的關鍵是,澤西不會解決所需的注入目標,如果父bean是不是在管理方面

import javax.enterprise.context.RequestScoped 

@RequestScoped 
@Path("room") 
public class RoomService { 

    @Inject 
    GameController gc; 

    public RoomService() {} 

    @Path("create") 
    @GET 
    @Produces("application/json") 
    public String create() { 
     Room r = new Room(); 
     gc.addRoom(r); // gc is null 
     return r.toJson(); 
    } 
} 

編輯:一定要有一個beans.xml的文件在你的WEB-INF文件夾。你在beans.xml文件看起來是這樣的:

<beans xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> 

    </beans> 

編輯:基於this JIRA,您可以用@ManagedBean

+0

你可以添加一個例子嗎?我試圖添加'@ RequestScoped'到jax-rs類,但它仍然不起作用。 – pepuch 2013-03-17 06:36:43

+0

@ pepuch,看我的編輯。還要確保你的WEB-INF中有beans.xml文件,否則CDI注入不會發生 – kolossus 2013-03-17 06:59:57

+0

ManagedBean看起來很奇怪嗎? – 2013-03-17 15:49:57

1

更換@RequestScoped內置的上下文對象的servlet,Web服務和EJB調用期間活躍,或者在對話上下文對象的情況下,用於JSF請求。

您可能很難從JAX-RS服務訪問請求,應用範圍和豆類,因爲它沒有明確規定這種情況的支持,但在你的情況下,它看起來像你只需要一個單身,而不是基於上下文豆。

如果你正在使用CDI(beans.xml文件)保持像這樣,

@Singleton 
public class GameController { 
    private Game game; 
    public GameController() { 
     this.game = new Game(new ArrayList<Room>()); 
    } 
.... 
} 

如果您使用的是帶有彈簧(無beans.xml文件)CDI則保持@Named

@Named 
@Singleton 
public class GameController { 
    private Game game; 
    public GameController() { 
     this.game = new Game(new ArrayList<Room>()); 
    } 
.... 
} 

如果上述不起作用,那麼我會建議將您的JAX-RS服務標記爲@ManagedBean以及上述更改,因爲不清楚CDI是否管理JAX-RS服務。

+0

謝謝。我會嘗試使用'@ Singleton'。爲什麼我使用了@ ApplicationScoped?我是JEE中的新成員,我認爲'ApplicationScoped' bean將像'Singleton'一樣工作。 – pepuch 2013-03-20 06:14:09

+0

因此'Singleton'是爲整個Jee容器創建的,'ApplicationScoped'只爲應用程序創建? – pepuch 2013-03-20 06:18:53

+1

如果beans.xml存在,Cdi創建它自己的bean容器,並通過創建新對象添加所有注入,除非指定爲單例,然後它使用同一個對象副本。當web應用程序的應用程序上下文被創建,銷燬時,cib容器將創建和移除Applicationscoped。 – 2013-03-20 06:25:31

相關問題