Serving static content with Jetty/Jersey/Guice

2019-06-25 23:26发布

问题:

Similar to another question (cf. Filtering static content Jersey) I want to serve static content from Jetty. There are several similar questions scattered all around the vast Internet, but most of them do not involve Guice, and those that do are completely out of date.

I have an existing service that uses Jersey (1.12) and Guice (3) with the following web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_2_5.xsd" version="2.5">
    <display-name>My Service</display-name>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <listener>
        <listener-class>com.example.MyGuiceConfig</listener-class>
    </listener>

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

</web-app>

MyGuiceConfig looks like so:

public class MyGuiceConfig extends GuiceServletContextListener
{
    @Override
    protected Injector getInjector()
    {
        return Guice.createInjector(new JerseyServletModule()
        {
            @Override
            protected void configureServlets()
            {
                bind(SomeResource.class);
                bind(SomeDao.class).to(ConcreteSomeDao.class);
                serve("/*").with(GuiceContainer.class);
            }
        });
    }
}

When I invoke the jetty-maven-plugin using mvn jetty:run, my service works as expected. But, any request to static content produces a 404.

How can I serve arbitrary static content without affecting my service? (i.e. The minimal change necessary that doesn't require me to change my tech stack?)

回答1:

How have you configured the url fragment that Jersey will handle in your JerseyServletModule? If you specify a prefix that doesn't conflict with your static content it should work.

public class Config extends GuiceServletContextListener {

  protected Injector getInjector() {
    return Guice.createInjector(
        new JerseyServletModule() {
          protected void configureServlets() {
            bind(Service.class);
            serve("/services/*").with(GuiceContainer.class);
          }
        });
  }

}

and

@Singleton
@Path("/service")
@Produces({MediaType.TEXT_PLAIN})
public class Service {

  @GET
  public String run() {
    return "Service running";
  }

}

should serve Servlet.class from host:8080/services/service and static resources that are included in the webapp...

EDIT See Jersey /* servlet mapping causes 404 error for static resources for another way to accomplish this without changing the path of your REST endpoint.