views:

507

answers:

3

I read over this post, which is similar to my issue, but had no luck solving the problem:

Basically I used to have the following servlet-mapping in my web.xml:

<servlet-mapping>
  <servlet-name>myServlet</servlet-name>
  <url-pattern>/index.html</url-pattern>
  <url-pattern>/channel1</url-pattern>
  <url-pattern>/channel2</url-pattern>
</servlet-mapping>

This worked perfectly until I needed to map the following url:

/channel1/{id}/{random_text}

Where {id} is a numeric ID value of my objects and {random_text} is just there just for "freindly urls". I managed to get this to work using the @RequestMapping in my controller as well as the @PathVariable to pull the variables from the URL.

However, the only way I managed to get the new URL to map successfully is be adding

<url-pattern>/</url-pattern>

to my web.xml at the bottom of my servlet-mappings. BUT, when I do this, all my other pages (/channel1, /channel2) display without access to the static content (css, jsp etc); I get a No mapping found for HTTP request with URI for the static files. I tried various combinations of mappings as suggested in the link I posted, but nothing worked. Any help would be great!!!

Update: my RequestMapping in the controller looks as follows (if it helps solve the problem at all..):

@RequestMapping(value = { "/channel1/{id}", "/channel1/{id}/{text}" })
+3  A: 

This worked perfectly until I needed to map the following url:

/channel1/{id}/{random_text}

This is to be covered by url-pattern of /channel1/*. Note the trailing /*. The url-pattern of /channel1 would not accept anything more in the pathinfo behind, it would only accept the exact URL and the optional query parameters.

BalusC
Yes I tried this (just tried again), and I get a 'No mapping found...' error when visiting the url...
es11
Then either the test/deploy was incorrect, or there's more in the mappings which coillides and/or got precedence.
BalusC
My mappings are exactly as I posted in the question. Is there a particular order that is necessary? Also I'm not sure that the deploy is at fault because everything else gets mapped properly except for the new url that I need.
es11
Also the `url-pattern` of `/`? This basically means "cover everything". Remove it from Spring dispatcher.
BalusC
Yea I only added the '/' mapping as a test. This was the only way I could get the url to map properly (with the side effect of no access to my css, jsp...files). I did try "/channel1/*" (WITHOUT the '/' mapping) and it did not work. I am not sure why..
es11
To the point: the URL's of static files should **not** match any of the `url-pattern` values of the Spring dispatcher servlet. If you have static files in `/channel1` folder, then this problem will indeed occur. Move them outside, e.g. `/static` or `/channel1static` or so.
BalusC
Thanks. This perfectly explains why I can't access my static files when using the '/' pattern. But its still a mystery as to why the '/channel1/*' doesn't capture requests to '/channel1/{id}/{...} ... i appreciate your help in any case
es11
Maybe the wrong `<dispatcher>` is been used. If you want to hook on "normal requests", use `REQUEST` (default), if you want to hook on internal forwards only, use `FORWARD`, if you want to hook on includes only, use `INCLUDE`.
BalusC
hmm it looks like its just that the pattern "/channel/*" isn't working. As a test I added the mapping "/channel1/1/test", then when I visited the url it worked! This is weird..is there any way to do wildcard matching in the url-mapping?
es11
`/channel/*` doesn't cover `/channel1/foo/bar`, only `/channel/foo/bar`. Use `/channel1/*`.
BalusC
that was just a typing error...see the answer I just posted for what the problem was. Thanks for all your help!
es11
+3  A: 

The best practice of doing things for rest format is to keep all your URL's which need to be processed by the DispatcherServlet in a separate namespace like web, so that the static resources will just be served directly and all your controller urls will be passed through Dispatcher, here is an example..

<servlet>
    <servlet-name>web</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>namespace</param-name>
        <param-value>web</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/web-servlet.xml</param-value>
    </init-param>

    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>web</servlet-name>
    <url-pattern>/web/*</url-pattern>
</servlet-mapping>
Teja Kantamneni
starting application URLs with /app/ is also common.
JacobM
A: 

I realized what the issue is (probably my fault for not elaborating on my @RequestMapping setup in the Controller earlier):

In my web.xml I had a url-pattern:

<url-pattern>/channel/*</url-pattern>

Also, in my controller I used the following mapping:

@RequestMapping(value = { "/channel1/{id}", "/channel1/{id}/{text}" })

The problem was that I was duplicating the /channel1 portion. I randomly (luckily) came across this post explaining this issue.

Long story short, when I changed my mapping in the controller to the following it works perfectly:

@RequestMapping(value = { "/{id}", "/{id}/{text}" })
es11