broadbear broadbear - 3 months ago 22
reST (reStructuredText) Question

Jersey 2.5 as filter http status 404

I have deployed a Jersey 2.5 application as a filter, but I get an HTTP Status 404 - Not Found error when accessing this (or any resource) url:

localhost:8080/[appname]/rest/users/new

This url worked previously when the app was deployed as a servlet. If I convert the 'filter' tags to 'servlet' tags, the url works again.

There is no exception on startup, and previously set breakpoints are no longer being fired. It is as if the resource classes aren't being found. Any idea what could be going wrong?

My web.xml:

<filter>
<filter-name>jerseywebapp</filter-name>
<filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.[pkg].resources</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
org.glassfish.jersey.media.multipart.MultiPartFeature,
org.glassfish.jersey.server.mvc.jsp.MvcFeature,
org.glassfish.jersey.server.mvc.jsp.JspMvcFeature,
org.glassfish.jersey.jackson.JacksonFeature
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.mvc.templateBasePath.jsp</param-name>
<param-value>/WEB-INF/views</param-value>
</init-param>
<!--
<load-on-startup>1</load-on-startup>
-->
</filter>
<filter-mapping>
<filter-name>jerseywebapp</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>

Answer

In my experience, changing the service tags to filter tags works the same, with the caveat that @Path("...") annotations will not assume to be matched within the context of the <url-pattern>. You'll have to add the pattern to the path annotation manually.

For example, with this XML in web.xml:

...
<servlet-mapping>
    <servlet-name>jerseywebapp</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

With this configuration, you can expect to get a match with this path annotation at /rest/test/ping:

@Path("test")
public class Test {

   @GET
   @Path("ping")
   public Response getPing() {
      ....
   }

Now, if we switch to using filter tags:

...
<filter-mapping>
    <filter-name>jerseywebapp</filter-name>
    <url-pattern>/rest/*</url-pattern>
</filter-mapping>

Note that to still hit our endpoint at /rest/test/ping, we need to change our class @Path annotation from "test" to "rest/test":

@Path("rest/test")
public class Test {

   @GET
   @Path("ping")
   public Response getPing() {
      ....
   }
Comments