2013-03-16 66 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

相关问题