2013-03-16 11 views
5

Stworzyłem usługę JAX-RS, w której chcę wstrzyknąć komponent o ograniczonej możliwości. Problem polega na tym, że fasola nie jest wstrzykiwana. Jak to się dzieje i jak mogę to rozwiązać?Nie można wstrzyknąć @ApplicationScoped bean w usłudze JAX-RS

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

Zastosowanie scoped fasoli

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

Twój kod 'GameController' nie kompiluje się i również brakuje' @Name'. Proszę nie zapisywać nietestowanego kodu. Zamiast tego użyj prawdziwego i przetestowanego kodu. – BalusC

+2

Naprawiłem to. Przepraszam. Dodałem '@Named', ale nadal nie działa. Myślę, że '@ Named' jest tylko dla' EL', dlatego nie dodałem tego wcześniej. – pepuch

+2

Dlaczego @Named? Nie zrobi żadnej różnicy. –

Odpowiedz

5

Musisz zrobić fasoli zarządzany zasób, aby kwalifikować się do wstrzykiwań. Na minimum, dodaj @RequestScoped do JAX-RS SIB, aby uczynić go godnym wstrzyknięcia.

Kolejna alternatywna adnotacja to @ManagedBean. Chodzi o to, Jersey nie zajmie pożądany cel wtrysku, jeśli rodzic nie jest fasola w zarządzanym kontekście

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

EDIT: należy mieć beans.xml plik w katalogu WEB-INF . Plik beans.xml będzie wyglądać mniej więcej tak:

<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> 

EDIT: Na podstawie this JIRA, można zastąpić @RequestScoped z @ManagedBean

+0

Czy możesz dodać przykład? Próbowałem dodać '@ RequestScoped' do klasy jax-rs, ale nadal nie działa. – pepuch

+0

@ pepuch, zobacz moją edycję. Upewnij się także, że w pliku WEB-INF znajduje się plik beans.xml, inaczej iniekcja CDI nie nastąpi. – kolossus

+0

ManagedBean wydaje się dziwny? –

1

Wbudowany obiekt kontekst jest aktywny podczas serwletu, usług internetowych i wywołania EJB lub w przypadku obiektu kontekstu konwersacji dla żądań JSF.

Być może masz trudności z uzyskaniem dostępu do żądania, zakresu i ziaren aplikacji z usługi JAX-RS, ponieważ nie określa ona wyraźnie tego wsparcia, jednak w twoim przypadku wydaje się, że potrzebujesz tylko pojedynczego, a nie opartego na kontekście fasola.

Należy to tak, jeśli używasz CDI (beans.xml)

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

Jeśli używasz CDI ze sprężyną (nie beans.xml), a następnie utrzymać @Named

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

Jeśli powyższe nie działa, zalecam oznaczenie usługi JAX-RS jako @ManagedBean wraz z powyższą zmianą, ponieważ nie jest jasne, czy CDI zarządza usługą JAX-RS.

+0

Dzięki. Spróbuję użyć '@ Singleton'. Dlaczego użyłem '@ ApplicationScoped'? Jestem nowy w JEE i pomyślałem, że komponent bean 'ApplicationScoped' będzie działał jak' Singleton'. – pepuch

+0

Tak więc "Singleton" jest tworzony dla całego kontenera Jeny, a "ApplicationScoped" jest tworzony tylko dla aplikacji? – pepuch

+1

Cdi tworzy własny kontener fasoli, jeśli bean.xml jest obecny i dodaje cały zastrzyk tam, gdzie jest to wymagane, tworząc nowe obiekty, chyba że podano je jako singleton, a następnie używa tej samej kopii obiektu. Applicationscoped są tworzone i usuwane przez kontener cdi, gdy kontekst aplikacji aplikacji internetowej jest tworzony, niszczony. –

Powiązane problemy