6

我创建了 JAX-RS 服务,我想在其中注入一个应用程序范围的 bean。问题是没有注入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;
    }

}
4

3 回答 3

7

您需要使 bean 成为托管资源以使其符合注入条件。至少,添加@RequestScoped到 JAX-RS SIB 以使其具有注入价值。

另一种替代注释是@ManagedBean. 关键是,如果父 bean 不在托管上下文中,Jersey 将无法解决所需的注入目标

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();
    }
}

编辑:确保在您的 WEB-INF 文件夹中有beans.xml文件。您的 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>

编辑:基于此 JIRA,您可以替换@RequestScoped@ManagedBean

于 2013-03-16T22:27:50.950 回答
1

内置上下文对象在 servlet、Web 服务和 EJB 调用期间是活动的,或者在会话上下文对象的情况下,用于 JSF 请求。

您可能难以从 JAX-RS 服务访问请求、范围和应用程序 bean,因为它没有明确说明对 this 的支持,但是在您的情况下,您似乎只需要一个单例而不是基于上下文的 bean。

如果您使用 CDI (beans.xml),请保持这样的状态,

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

如果您将 CDI 与 Spring(无 beans.xml)一起使用,请保留@Named

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

如果上述方法不起作用,那么我建议将您的 JAX-RS 服务@ManagedBean与上述更改一起标记,因为尚不清楚 CDI 是否管理 JAX-RS 服务。

于 2013-03-20T02:45:06.363 回答
-1

cdi-api.jar添加到您的项目中。

于 2015-10-04T12:04:47.817 回答