Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Guice & Jersey multiple URL patterns to same servlet while applying package filtering

I am trying, using Jersey & Google Guice 3.0, to map 2 different URL patterns to the same servlet and each of these URL patterns to be applied to a different package in my project.

To be clear I am pasting part of the code below and I will also explain.

web.xml

<listener>
    <listener-class>com.abc.web.listeners.GuiceContextListener</listener-class>
</listener>
<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>

GuiceContextListener

public final class GuiceContextListener extends GuiceServletContextListener {
...
    private JerseyServletModule getJerseyServletModule() {
        JerseyServletModule jerseyModule = new JerseyServletModule() {
            @Override
            protected void configureServlets() {
                filter("/*").through(WebServerStateFilter.class);
                final Map<String, String> params = new HashMap<String, String>();
                StringBuilder sb = new StringBuilder();
                sb.append("com.abc.web.stats.services");
                params.put(PackagesResourceConfig.PROPERTY_PACKAGES, sb.toString());
                serve("/api/v1/*").with(GuiceContainer.class, params);

                final Map<String, String> params1 = new HashMap<String, String>();
                StringBuilder sb1 = new StringBuilder();
                sb1.append("com.abc.web.stats.otherservices");
                params1.put(PackagesResourceConfig.PROPERTY_PACKAGES, sb1.toString());
                serve("/api/*").with(GuiceContainer.class, params1);
            }
        }
    }
...
}

So basically I want:

  • URLs starting with "/api/v1/*" to be handled through servlet GuiceContainer by services in package "com.abc.web.stats.services"
  • URLs starting with "/api/*" to be handled through same servlet GuiceContainer by services in package "com.abc.web.stats.otherservices"

I used the code above but it does not seem to work, it seems that only the first "serve" call is taken into consideration so in this case only URLs matching "/api/v1/*" are served. I do not want to hardcode "v1" in my services since the version might change (to "v2") in the future.

Can somebody help me out?

Thanks, Paul

like image 283
Paul Chiritescu Avatar asked May 15 '13 15:05

Paul Chiritescu


People also ask

Why we use Google Guice?

Beyond Dependency Injection, the benefits of using Google Guice is: Guice has a very clean implementation of constructor Injection. As you can see from the example you just add @Inject annotation constructor. Guice also has setter Injection using the same annotation.

What does Guice module do?

In Guice, it is defined by an implementation of a Guice Module. Guice provides an AbstractModule , used here, which provides some syntactic convenience. This Module simply defines the mapping of interfaces to implementations, e.g., binding injections requiring an OrderService to the DefaultOrderService implementation.

How can I learn Google Guice?

Guice is an open source, Java-based dependency injection framework. It is quiet lightweight and is actively developed/managed by Google. This tutorial covers most of the topics required for a basic understanding of Google Guice and to get a feel of how it works.


1 Answers

Maybe your current endpoints should be refactored, but anyway your code looks a bit more complicated than neccesary. In my case it works like this.

...
String packages = "com.abc.web.stats.services;com.abc.web.stats.otherservices";
params.put(PackagesResourceConfig.PROPERTY_PACKAGES, packages);

serve("/api/v1/*").with(GuiceContainer.class, params);
serve("/api/*").with(GuiceContainer.class, params);
...

Jersey can scan multiple packages with a list separated by ;

Maybe you should change your "api/*" endpoint but I'm not really sure about how Jersey will work in that situation. I could bet it works fine with this code.

like image 158
ydarias Avatar answered Sep 23 '22 10:09

ydarias