2016-07-22 25 views
1

Ich versuche, Jerseys @QueryParam und Guices @Inject zusammen in einem Ressourcenkonstruktor zu verwenden. Von der Suche im Web hat es ähnliche Fragen gewesen Mine vor gefragt:
How can I mix Guice and Jersey injection?
http://users.jersey.dev.java.narkive.com/zlGMXuBe/can-queryparam-be-used-in-resource-constructor-along-with-guice-injectionWie kann ich die @QueryParam- und Guice-Injektion von Jersey in einem Ressourcenkonstruktor verwenden?

Es scheint, es ist nicht möglich. Diese Fragen sind jedoch mehrere Jahre alt, also was versuche ich jetzt zu tun?

Hier ist ein Code von dem, was ich versuche, als Beispiel zu tun:

@Path("/mypath") 
public class MyResource { 
    private Manager manager; 
    private String type; 

    @Inject 
    public MyResource(Manager manager, 
        @QueryParam("type") String type) { 
    this.manager = manager; 
    this.type = type; 
    } 

    @GET 
    @Produces("text/plan") 
    @Path("/{period}") 
    public String myMethod(@PathParam("period") String period) { 
    return manager.foo(period, type); 
    } 
} 

Dank!

+1

Das macht keinen Sinn? 'MyResource' ist ein Singleton und behandelt alle Anfragen. Zum Zeitpunkt der Erstellung gibt es keine Anfrage und daher auch kein '@ QueryParam'. –

+0

@LanceJava Wenn Sie das Guice '@ Inject'-Zeug entfernen, funktioniert es. Sie können einen Abfrageparameter mit der Anfrage übergeben und der Konstruktor wird es auf alles setzen, was Sie übergeben haben. –

+0

Ok, kein Jersey Benutzer selbst. Spring mvc usw. verwenden Singletons anstatt pro Anfrage Eventhandler. Ich kann nur annehmen, dass Sie irgendwie in den Jersey Injektor stecken müssen –

Antwort

1

Es funktioniert für mich. Vielleicht ist ein Problem im Zusammenhang mit der korrekten Bindung von Jersey und Guice.

Ich habe eine minimale Webanwendung mit Ihrer Ressourcendefinition und einigen Standardcode erstellt.

Zunächst wird die App-Initialisierung:

@WebListener 
@Singleton 
public class AppContextListener implements ServletContextListener { 
    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     new GuiceBootstrap().contextInitialized(sce); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
     // no op 
    } 
} 

Sie es sehen können, dass ich Guice dort initialisieren. Hier ist der Guice-Code.

public class GuiceBootstrap extends GuiceServletContextListener { 
    @Override 
    protected Injector getInjector() { 
     return Guice.createInjector((Module) binder -> binder.bind(Manager.class) 
                  .to(ManagerImpl.class)); 
    } 
} 

Es ist Java 8-Syntax, aber wenn Sie nicht Java 8 verwenden, ist es leicht in Pre-Lambda-Code umwandelbar. Ich erstelle einen Guice-Injektor mit nur einer Bindung.

Die Manager und die Implementierungsklasse sind sehr einfach.

public interface Manager { 
    String foo(String period, String type); 
} 

public class ManagerImpl implements Manager { 
    @Override 
    public String foo(String period, String type) { 
     return "Got " + period + " " + type; 
    } 
} 

Schließlich wird der Code, den Jersey initialices und bindet seinen internen Injektor (HK2) zu Guice.

@ApplicationPath("api") 
public class ApiRest extends ResourceConfig { 

    @Inject 
    public ApiRest(ServiceLocator serviceLocator, ServletContext servletContext) { 
     packages("net.sargue.so38531044"); 
     GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); 
     GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); 
     Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName()); 
     if (injector == null) 
      throw new RuntimeException("Guice Injector not found"); 
     guiceBridge.bridgeGuiceInjector(injector); 
    } 
}