57

I'm trying to build a Servlet that calls a JSP page similar to the following:

public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {
    req.getRequestDispatcher("/WEB-INF/main.jsp").forward(req, resp);
}

I need this Servlet to respond to the domain's root (eg: http://example.com/) so I'm using the following mapping in the web.xml:

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

The problem I'm having is that this matches EVERYTHING, so when the dispatcher forwards to "/WEB-INF/main.jsp" this matches the url-pattern so the Servlet gets run again. This results in a loop that runs until it dies with a java.lang.StackOverflowError.

How can I match the root without preventing other scripts from being runnable?

Noman
  • 887
  • 1
  • 15
  • 34
Jeremy Logan
  • 47,151
  • 38
  • 123
  • 143
  • you wont be able to do that you have to use hacks i tried the same on appengine see here http://stackoverflow.com/questions/870150/how-to-access-static-resources-when-using-default-servlet but not working – Rahul Garg Jun 23 '09 at 09:01
  • 3
    Maybe time for an accepted answer? – Jeb Nov 24 '14 at 17:11

8 Answers8

49

Use an empty pattern, e.g.

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern></url-pattern>
</servlet-mapping>

The servlet 3.0 spec has clarified this:

The empty string ("") is a special URL pattern that exactly maps to the application's context root

So it should at least work on a 3.0 container, and I've verified that it works on Jetty 8

nilskp
  • 3,097
  • 1
  • 30
  • 34
29

Using the welcome-file element of web.xml worked for me, on app engine. Here's mine:

<web-app>
    <servlet>
        <servlet-name>RootServlet</servlet-name>
        <servlet-class>com.foo.RootServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RootServlet</servlet-name>
        <url-pattern>/foo</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>foo</welcome-file>
    </welcome-file-list>
</web-app>
Jeb
  • 15,939
  • 6
  • 34
  • 37
  • 1
    This works great. Just be aware the 'servlet-name' cannot be the same as the 'welcome-file'. – nunaxe Jan 22 '12 at 15:14
  • Doesn't seem to work for me on Jetty or Tomcat. Only when the welcome file is an actual file does it open it correctly. – Jus12 Nov 15 '13 at 12:39
  • Works like a charm in Apache Tomcat, even though the solution offered by @nilskp is a bit lighter :) – user3856210 Nov 11 '14 at 22:26
  • @Jus12 Any file that is named in the `web.xml` should be an existing file. Even if a servlet (or even a faclets file) is mapped to it. – Usagi Miyamoto Jan 28 '17 at 19:19
  • Aaaaaah that's why my welcome file was not working ! The"/" need to be removed ! So if your servlet url-pattern is /Blabla your welcome file need to be "Blabla" without the "/". Great ! Best solution ! Thank you ! – Claod Feb 25 '17 at 18:52
7

The original question doesn't mention that they're trying to map a root servlet on App Engine - it's easy on Tomcat (and other servlet containers as far as I know) but App Engine isn't a normal servlet container.

My normal way of building a web application with servlets is to extend HttpServlet, add a "page" object with title, content, errors, messages etc. and for output forward to a JSP template. This has been an absolute nightmare getting working in App Engine.

  • JSP files can't be "named" without a "/" at the beginning.
  • JSP files can't be in a subdirectory
  • Servlets can't be mapped to the root of your application with a "/" url-pattern

Here's my web.xml (edited for brevity) which finally worked.

<web-app>
  <servlet>
    <!-- this servlet needs to redirect to a NamedDispatcher
         called "template" -->
    <servlet-name>Home</servlet-name>
    <servlet-class>my.domain.HomeSv</servlet-class>
  </servlet>
  <servlet>
    <!-- jsp file must apparently be in root directory and have "/" at
         start of path -->
    <servlet-name>template</servlet-name>
    <jsp-file>/template.jsp</jsp-file>
  </servlet>
  <servlet-mapping>
    <!-- map your home servlet to somewhere other than "/" -->
    <servlet-name>Home</servlet-name>
    <url-pattern>/home</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <!-- make your Home servlet the welcome file -->
    <welcome-file>home</welcome-file>
  </welcome-file-list>
</web-app>

I haven't been particularly scientific about validating all this - but it seems to work for me now and I'm pretty happy about that.

Sam Lowry
  • 119
  • 1
  • 3
  • 1
    On the dev server, it seems that adding a fallback index.html will cause that index.html to take precedence over your servlet, if it exists, even if it is specified _after_ the home. – hraban Jul 30 '16 at 22:24
4

You can create a welcome file named index.jsp in the root with the following code using JSTL or otherwise.

<c:redirect url="/main"/>

So in the web.xml file you will have this:

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>        
</welcome-file-list>

So anyone requesting the root will be redirected to /main. Now your servlet can be mapped to main.

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/main</url-pattern>
</servlet-mapping>
Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
  • 2
    Ok, I get that this would work, but it fells like such a hack. Is it really not possible to have a servlet handle the root on its own? – Jeremy Logan Jun 23 '09 at 02:25
  • Sorry for voting down but there is a better solution - http://stackoverflow.com/questions/1030302/how-can-i-map-a-root-servlet-so-that-other-scripts-are-still-runnable/4443581#4443581 – Maxim Kachurovskiy Jan 30 '11 at 12:27
  • This solution has the advantage that it doesn't create a mapping in every directory, the way welcome-files do. So I used it (though with plain <% scriptlet, not a tag) and I'm voting it up. – Rob N Jul 15 '11 at 14:31
1

Try just to remove '*' from the pattern, i.e.

<url-pattern>/</url-pattern>
Gennady Shumakher
  • 5,637
  • 12
  • 40
  • 45
  • @fiXedd has apparently tried that and it doesn't work. (See my answer's edit history.) Maybe something to do with running on App Engine... – Stu Thompson Jun 23 '09 at 07:03
1

A solution is mentioned in another thread URL Pattern for servlet mapping in web.xml using URLrewrite -> http://tuckey.org/urlrewrite/

Community
  • 1
  • 1
Tomasz
  • 5,269
  • 8
  • 56
  • 65
  • 1
    Thanks for turning me on to this urlrewrite thing. This got my java webapp with durandal to work, I was having some weird problem with it adding the routing alias infront of the url. – Jake Gaston Feb 23 '18 at 22:19
0

You can't redirect to WEB-INF. A servlet container will never serve requests for documents in that folder.

If you want your application (not just a servlet, but the entire application) to be available under the root context ("/" of "http://www.domainname.com/"), then you need to set up a context entry for it - not a servlet mapping.

With Tomcat, you add a new <Context> mapping (in one of about 3 different possible places).

matt b
  • 138,234
  • 66
  • 282
  • 345
  • 1
    I'm not doing a redirect, I'm doing a forward. That's internal, so it souldn't matter if they're publicaly visible, right? Either way, moving them out of the WEB-INF didn't help. I'm not using Tomcat, but I'll look in to context mapping, thanks. – Jeremy Logan Jun 23 '09 at 02:24
  • The container will serve resources under WEB-INFs when the request is being forwarded. It's a valid, and useful site structure paradigm. – Alex Jun 24 '09 at 05:38
0

Have you tried the below? (Note the missing *, which is a wild card and is the reason that your configuration catches everything.)

<servlet-mapping>
        <servlet-name>MainServlet</servlet-name>
        <url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

(Edited as per comments from just /.)

Stu Thompson
  • 38,370
  • 19
  • 110
  • 156
  • I did... it had the exact same result. I should have mentioned I'm doing this on App Engine. I'm starting to think they're mapping is, uh, wonky. – Jeremy Logan Jun 23 '09 at 05:10