2

I have a simple servlet which renders different content based on different geo locations for example:

example.com/us
example.com/de
example.com/uk
example.com/..

so actually the servlet should supports all geo locations as url-pattern. So thats why I defined the rule below in my web.xml file:

<servlet-mapping>
  servlet-name>MyServlet</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

this is how the servlet look like:

public class MyServlet extends HttpServlet{
  String showPage = "/pages/show.jsp";
  public void doGet(HttpServletRequest request, HttpServletResponse response){
    System.out.println("servlet initiated... ~> "+request.getRequestURI());
    ...
    request.getRequestDispatcher(showPage).forward(request, response);

  }

}

As soon as I try to forward the page, the servlet starts again and again; it tries to also handle the request /page/show.jsp. So I get such an ouput when I try to access example.com/us:

servlet initiated... ~> /us
servlet initiated... ~> /page/show.jsp
Exception...
servlet initiated... ~> /page/show.jsp
Exception...
servlet initiated... ~> /page/show.jsp
...

It throws an exception because my servlet is not expecting such a url-pattern /page/show.jsp but it triggers because I have define /* url-pattern in my web.xml file.

Any idea? how can I skip or exclude the unwanted requests like the one above? Thanks.

tokhi
  • 21,044
  • 23
  • 95
  • 105
  • what is your exception ? – erencan Jun 04 '14 at 16:39
  • @erencan: the exception complains about the `/page/show.jsp` request. So after `/us` I want the servlet to stop and not process other requests like `/page/show.jsp` – tokhi Jun 04 '14 at 16:43
  • Your question is not clear. You have already redirected the request to `/pages/show.jsp` I think, you have not posted all the code, exactly the code which throws exception. – erencan Jun 04 '14 at 16:47

4 Answers4

1

I could not find a specific reference but I believe that "/*" root url pattern conflicts with the default mapping in the the global web.xml which could be contributing to your problem.

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- The mapping for the default servlet -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

try adding explicit jsp servlet tag and servlet mapping to avoid processing the jsp through the default mapping which is created with the "/" root url pattern. I'm not sure that this will solve your problem.

<servlet>
<servlet-name>showpage</servlet-name>
<jsp-file>/pages/show.jsp</jsp-file>
</servlet>

<servlet-mapping>
<servlet-name>showpage</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>

Another more explicit solution would be to create a url pattern that differentiates all of the country geo requests.

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/geo/*</url-pattern>
</servlet-mapping>

So example.com/geo/us etc will map explicitly

I attempted the same global setting and had a similar problem where it recursively attempted the request and threw an exception over and over until I stopped the Tomcat server. The problem was resolved when used more specific url pattern.

Threadid
  • 730
  • 1
  • 7
  • 27
1

Bart answer gave me the clue. Actually there are many ways to handle this, one is to use Filters and the other one is to define all the static routes in web.xml and instead of the /* I have used /.

So to resolve the issue I change the url-pattern as below:

<!-- static assets -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>

<!-- my servlet -->
<servlet-mapping>
  servlet-name>MyServlet</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

You also don't need to define the pattern for org.apache.catalina.servlets.DefaultServlet its already there by default. So After above changes everything works fine.

tokhi
  • 21,044
  • 23
  • 95
  • 105
0

When resolving pages/show.jsp the container will match on the longest path first then look at the file extension (.jsp) afterwards. So pages/show.jsp matches /* and therefore the container loads the Servlet again and doesn't initiate the JSP engine servlet.

Are all your jsps in a pages directory? Maybe you can add that mapping to your web.xml

<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/pages/*</url-pattern>
</servlet-mapping>
Si Kelly
  • 703
  • 3
  • 9
0

Per the servlet specification (2.5 here, but it should be the smae for newer version) :

  1. The container will try to find an exact match of the path of the request to the path of the servlet. A successful match selects the servlet.
  2. The container will recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the ’/’ character as a path separator. The longest match determines the servlet selected.
  3. If the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that handles requests for the extension. An extension is defined as the part of the last segment after the last ’.’ character.
  4. If neither of the previous three rules result in a servlet match, the container will attempt to serve content appropriate for the resource requested. If a "default" servlet is defined for the application, it will be used.

(source : servlet-spec-2.5)

So for your case, it should be sufficient to add a more precise mapping (as said by Si Kelly) :

 <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/pages/show.jsp</url-pattern>
 </servlet-mapping>
Cédric Couralet
  • 4,913
  • 1
  • 21
  • 21