简体   繁体   English

Guice - Jersey - Servlet绑定

[英]Guice - Jersey - Servlet binding

I recently switched to two phase injection and this has created an error in my servlet binding. 我最近切换到两阶段注入,这在我的servlet绑定中创建了一个错误。 I am currently toggling between two error modes and not sure which direction is best to pursue. 我目前正在两种错误模式之间切换,不确定哪种方向最好。

The first error I encountered was: 我遇到的第一个错误是:

com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes. com.sun.jersey.api.container.ContainerException:ResourceConfig实例不包含任何根资源类。

My servlet module looked like this: 我的servlet模块看起来像这样:

public class MyServletModule extends JerseyServletModule {
    @Override
    protected void configureServlets() {
        bind(MyServlet.class).asEagerSingleton();

        serve("/*").with(GuiceContainer.class);
    }
}

I was able to remove this error by explicitly providing the com.sun.jersey.config.property.packages parameter. 我能够通过显式提供com.sun.jersey.config.property.packages参数来删除此错误。

public class MyServletModule extends JerseyServletModule {

    @Override
    protected void configureServlets() {
        bind(MyServlet.class).asEagerSingleton();

        Map<String,String> parameters = new HashMap<String, String>();
        parameters.put(PackagesResourceConfig.PROPERTY_PACKAGES, MyServlet.class.getPackage().getName());
        serve("/*").with(GuiceContainer.class, parameters);
    }
}

But when I do this, Guice attempts a Just in Time binding which does not respect the @Inject on my servlet constructor. 但是当我这样做时,Guice尝试了一个Just in Time绑定,它不尊重我的servlet构造函数上的@Inject。

com.google.inject.ConfigurationException: Guice configuration errors: com.google.inject.ConfigurationException:Guice配置错误:

1) Unable to create binding for MyServlet. 1)无法为MyServlet创建绑定。 It was already configured on one or more child injectors or private modules bound at MyServletModule.configureServlets(MyServletModule.java:44) If it was in a PrivateModule, did you forget to expose the binding? 它已经在MyServletModule.configureServlets绑定的一个或多个子注入器或私有模块上配置(MyServletModule.java:44)如果它在PrivateModule中,您是否忘记公开绑定? while locating MyServlet 在找到MyServlet时

1 error at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:150) com.google.inject.internal.InjectorImpl.getBinding上的1个错误(InjectorImpl.java:150)

My servlet has an @Inject constructor who's arguments cannot be bound just in time. 我的servlet有一个@Inject构造函数,它的参数不能及时绑定。 After debugging into InjectorImpl, I believe this is the reason that things fail when I use PROPERTY_PACKAGES. 在调试InjectorImpl后,我相信这就是我使用PROPERTY_PACKAGES时失败的原因。

I'm just not sure if using PROPERTY_PACKAGES is correct and I need to fix some bindings? 我只是不确定使用PROPERTY_PACKAGES是否正确,我需要修复一些绑定? Or if that is the wrong direction and I need to fix the original ResourceConfig error in a different way. 或者,如果这是错误的方向,我需要以不同的方式修复原始的ResourceConfig错误。

Help or a push in the right direction is appreciated. 感谢帮助或推动正确的方向。

I was able to bind Jersey resources to Guice without using the bind-parameters (without explicitly providing the com.sun.jersey.config.property.packages parameter), by binding resources separately 我能够将Jersey资源绑定到Guice而不使用bind-parameters(没有显式提供com.sun.jersey.config.property.packages参数),通过单独绑定资源

public class BindJerseyResources extends ServletModule {

    @Override
    protected void configureServlets() {
        // excplictly bind GuiceContainer before binding Jersey resources
        // otherwise resource won't be available for GuiceContainer
        // when using two-phased injection
        bind(GuiceContainer.class);

        // bind Jersey resources
        PackagesResourceConfig resourceConfig = new PackagesResourceConfig("jersey.resources.package");
        for (Class<?> resource : resourceConfig.getClasses()) {
            bind(resource);
        }

        // Serve resources with Jerseys GuiceContainer
        serve("/*").with(GuiceContainer.class);
    }
}

The resources are like following 资源如下

@Path("/")
@RequestScoped
public class Resource {

    private Storage storage;

    @Inject
    public Resource(Storage storage) {
        this.storage = storage;
    }

    @GET
    @Path("get/{name}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getGuid(@PathParam("name") String name) {
        return storage.get(name);
    }
}

Maybe this helps you to avoid the latter problematic binding. 也许这可以帮助您避免后一个有问题的绑定。


Updated the answer to work with two-phased injection. 更新了使用两阶段注射的答案。

Java Part Java部分

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.persist.jpa.JpaPersistModule;
import com.google.inject.servlet.GuiceServletContextListener;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.thjug.apipublic.Echo;

public class ServletContextListener extends GuiceServletContextListener {

    @Override
    protected Injector getInjector() {
        final Injector injector = Guice.createInjector(new JerseyServletModule() {
            @Override
            protected void configureServlets() {
                bind(Echo.class);
                bind(ServletContainer.class).in(Singleton.class);
                serve("/*").with(GuiceContainer.class);
            }
        }, new JpaPersistModule("dbUnit"), new LoggingModule());

        injector.getInstance(JPAInitializer.class);
        return injector;
    }
}

web.xml web.xml中

    <distributable />

    <display-name>API</display-name>

    <filter>
            <filter-name>guiceFilter</filter-name>
            <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
            <filter-name>guiceFilter</filter-name>
            <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
            <description>Guice Initiate</description>
            <listener-class>com.thjug.base.ServletContextListener</listener-class>
    </listener>

Below is my keynote about How to make REST with Guice http://www.slideshare.net/nuboat/lightweight-javaee 以下是关于如何使用Guice进行REST的主题演讲http://www.slideshare.net/nuboat/lightweight-javaee

这是一篇关于如何进行绑定的文章(包括完整的源代码): implementation-distributed-counter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过Maven Tomcat的Jersey Guice Servlet-404 - Jersey Guice Servlet via Maven Tomcat - 404 Guice + Jersey:添加所有资源和提供程序而不绑定到 Jersey Servlet - Guice + Jersey: Add all resources and providers without bind to Jersey Servlet 使用Guice Injections对JAX-RS / Jersey servlet进行单元测试 - Unit testing JAX-RS/Jersey servlet with Guice Injections 动态每个REST(Jersey)请求绑定Guice中的配置 - Dynamic per REST(Jersey) request binding of configurations in Guice 使用Guice-servlet / Jetty / Jersey的轻量级Java Web堆栈 - 一些问题 - Light Java web stack using Guice-servlet/Jetty/Jersey - some questions Google Guice&Jersey将多个URL模式应用于同一servlet,同时应用包过滤 - Google Guice & Jersey multiple URL patterns to same servlet while applying package filtering 在com.sun.jersey.guice.spi.container.servlet.GuiceContainer中找不到合适的构造函数 - Could not find a suitable constructor in com.sun.jersey.guice.spi.container.servlet.GuiceContainer 在使用Guice servlet配置时,如何在Jersey WS调用中启用跟踪 - How to turn on tracing in Jersey WS calls, when using Guice servlet configuation 泽西岛和Google Guice集成 - Jersey and Google Guice integration Jersey Guice整合例外 - Jersey Guice Integration exception
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM