users@jersey.java.net

Re: Jersey with Spring always giving 404 for subresources

From: Jason Erickson <jason_at_jasonerickson.com>
Date: Wed, 24 Nov 2010 10:28:13 -0800

I think the tracing cleared things up for me. (Thanks for the tip on how to configure that.) You can correct me if I'm wrong. Here's my new understanding:
You only want one servlet mapping for the spring servlet.
It can be any path you want.
The paths you configure in your beans should be relative to the path of the servlet, not the path of the application. (I believe this was my main mistake).
You may be able to do more than one servlet mapping, but that's not a typical scenario.

Originally, I had one mapping - "/ws/*" but I got 404 errors for everything. Then I moved everything to root and had the multiple mappings and everything worked fine _for those mappings_ but not sub-resources. So, with a url-pattern of /obs/*, getting a resource from /obs worked, but /obs/1 or obs/meta didn't. Finally, I took a flier since the examples worked and they took _all_ the requests by mapping /, so I just tried the same with mine and it worked.

Now I just configured tracing (in Jetty) and tried again with "/ws/*" and I got the 404 on /ws/obs/1, but here is the trace (or part of it):
INFO: 1 * Server in-bound request
1 > GET http://localhost:8080/factorlab-ws/ws/obs/1
1 > Authorization: Basic ZGVtbzpkZW1v
1 > User-Agent: curl/7.19.7 (i386-apple-darwin10.2.0) libcurl/7.19.7 zlib/1.2.3
1 > Host: localhost:8080
1 > Accept: */*
1 >

Nov 24, 2010 10:13:02 AM com.sun.jersey.spi.container.ContainerResponse traceException
INFO: Mapped exception to response: 404 (Not Found)
com.sun.jersey.api.NotFoundException: null for uri: http://localhost:8080/factorlab-ws/ws/obs/1
--- snip ---
Nov 24, 2010 10:13:02 AM com.sun.jersey.api.container.filter.LoggingFilter$Adapter finish
INFO: 1 * Server out-bound response
1 < 404
1 < X-Jersey-Trace-000: accept root resource classes: "/obs/1"
1 < X-Jersey-Trace-001: match path "/obs/1" -> "/application\.wadl(/.*)?", "/ws(/.*)?"
1 < X-Jersey-Trace-002: mapped exception to response: com.sun.jersey.api.NotFoundException_at_4b935405 -> 404
1 <

So it looks to me like it's looking for /obs/1. In my current iteration of the application (changed since my first query) I have a RootWebResource with @Path("ws") that returns sub-resources, meaning the ObservationResource gets returned by the RootWebResource on path "ws/obs" and there is no @Path on ObservationResource.

So for my next experiment, I added the @Path("obs") annotation to the ObservationResource, and requests to that resource (and its sub-resources) now work.

On Nov 24, 2010, at 1:37 AM, Paul Sandoz wrote:

>
> On Nov 23, 2010, at 8:14 PM, Jason Erickson wrote:
>
>> OK, I figured out the problem - it was in my web.xml. I had configured several paths for servlet mapping to the Jersey Spring servlet, but that didn't work. What did work was:
>> <servlet-mapping>
>> <servlet-name>jersey-spring</servlet-name>
>> <url-pattern>/</url-pattern>
>> </servlet-mapping>
>>
>> I could not get any other mapping to work - giving me 404's on everything except for the explicit mapping path. Is this a bug? Or is there some reason why this is supposed to be the way it works?
>>
>
> I noticed you had multiple declarations of the servlet mapping for "jersey-spring" was that intentional?
>
> Did you replace all those mappings with the one above?
>
> Given the way sub-resource matching works and what you say the request for the sub-resource is not even getting through to the Jersey runtime. You can confirm by enabling tracing and logging:
>
> <init-param>
> <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
> <param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
> </init-param>
> <init-param>
> <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
> <param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
> </init-param>
> <init-param>
> <param-name>com.sun.jersey.config.feature.Trace</param-name>
> <param-value>true</param-value>
> </init-param>
>
>
> I wonder if there is a bug in Jetty? can you try a test and deploy on Tomcat?
>
> Paul.
>
>> On Nov 17, 2010, at 12:32 PM, Jason Erickson wrote:
>>
>>> One more thing: When I put a breakpoints in the getTestText() and getTimelineResource() methods below and debug, a request to /reports will break, but a request to /reports/testitem doesn't, implying that it never enters the getTimelineResource method.
>>>
>>> On Nov 17, 2010, at 12:10 PM, Jason Erickson wrote:
>>>
>>>>> @Path("testitem")
>>>>> public TestItemResource getTimelinResource() {
>>>>> return timelineResource;
>>>>> }
>>>>>
>>>>> @GET
>>>>> @Produces(MediaType.TEXT_PLAIN)
>>>>> public String getTestText() {
>>>>> return "Success!\n";
>>>>> }
>>>
>>
>