5

I'm still pretty new to programming Java servlets, so apologies in advance if I'm going about this wrong. (But if so, I'd appreciate any help!)

My web site is going to have two main parts: a web service part and an "everything else" part, the latter of which will be servicing most of the interactive browser requests. I thought I'd be able to get away with something like this in my web.xml file:

<servlet>
    <servlet-name>Webservice</servlet-name>
    <servlet-class>com.mydomain.webservice</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Webservice</servlet-name>
    <url-pattern>/webservice/*</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Interactive</servlet-name>
    <servlet-class>com.mydomain.interactive</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Interactive</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

The intention is for the web service, which communicates via either AJAX, via a fat client application, or other RPC method, to use URLs that all start with mydomain.com/webservice, such as:

  • mydomain.com/webservice/login
  • mydomain.com/webservice/viewuser/12345
  • mydomian.com/webservice/deleteitem/abc
  • ...

However, people browsing the site normally using a browser would access the site as:

  • mydomain.com (home page)
  • mydomain.com/login
  • mydomain.com/viewuser/12335
  • mydomain.com/deleteitem/abc
  • ...

In my interactive class, I'm parsing the getPathInfo() result to forward the request to another class, and the vast majority of most of those classes are using a request dispatcher to forward info to view JSP files to actually render the HTML. So a snipped of code in one of my classes might look like:

RequestDispatcher view = req.getRequestDispatcher("/WEB-INF/views/master.jsp");
view.forward(req, resp);

I also do have error checking in the interactive servlet so that if a user tries to access a URL that isn't routable (for example, mydomain.com/foobar when I haven't defined anything to handle foobar), it throws an HTTP 404. When I fire it up, though, everything generates an HTTP 404.

After some troubleshooting, I figured out that the request is making it to the servlet without any issue, and the servlet is parsing it correctly. However, when it tries to forward it to /WEB-INF/views/master.jsp, it invokes the servlet again. I thought that WEB-INF was a "magic" directory that represented publicly inaccessible resources, but it looks like my Java container (Jetty, via the Google App Engine plug-in for Eclipse) is treating it like an attempt to access a URL. I'm guessing it's because when I define /* as the url-pattern in my web.xml file, it's literally interpreting that as, send everything to that servlet, including calls to forward a request to a JSP view file within the WEB-INF directory.

Am I doing something wrong? I haven't even gotten to trying to handle requests to the web service yet and I've gotten stuck on just trying to handle requests to the interactive site. Any help would be greatly appreciated!

informatik01
  • 16,038
  • 10
  • 74
  • 104
King Skippus
  • 3,801
  • 1
  • 24
  • 24
  • remove the /WEB-INF from the request and check – sreejith Jul 30 '12 at 04:13
  • I've tried it as all of the following: /WEB-INF/views/master.jsp, WEB-INF/views/master.jsp, /views/master.jsp, and views/master.jsp. It all does the same thing--it invokes the servlet twice: once on the first pass with getPathInfo() returning the path I used to send the request (for example, `/viewuser/12335`), and then a second time with the string that's the parameter of getRequestDispatcher(). I don't think the problem is with that path; it seems to me a web.xml problem that requests for /WEB-INF are going to my servlet. I don't know how to fix it and process "everything else" URLs, though. – King Skippus Jul 30 '12 at 05:18
  • here one thing which u can do is rather than putting /* u can use some filter which will only filter your servlet requests , not jsp requests – sreejith Jul 30 '12 at 06:21
  • /* takes everything from your context-path and also WEB-INF is part of it. – chaosguru Jul 30 '12 at 07:17
  • also which framework are you using for MVC? – chaosguru Jul 30 '12 at 07:19
  • In this case, you should create a class that implements [`Servlet`](http://docs.oracle.com/javaee/6/api/javax/servlet/Servlet.html) interface (not a class that extends [`HttpServlet`](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html)). JSF framework has the `javax.faces.webapp.FacesServlet`, an implementation that handles this kind of problems, and you could define your servlet mapping like *.jsp or *.xhtml if you use JSF 2.x – Luiggi Mendoza Jul 30 '12 at 07:41
  • @chaosguru: I'm not using a framework, I wrote my own code in my servlet to handle dispatching the request to the appropriate classes. – King Skippus Jul 30 '12 at 20:59

1 Answers1

1

The solution to your original problem is very easy - you should configure your servlet as a default one:

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

Note the / pattern. This way it will handle requests not handled by other servlets (unlike /* mapping, that handles all the requests).

However, this approach causes problems with serving static content. If you have static content to be served you may need more sophisticated solutions, see, for example, Using Spring, mapping to root in web.xml, static resources aren't found.

Community
  • 1
  • 1
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 2
    Here's a simpler sophisticated solution for the case you don't use Spring: http://stackoverflow.com/questions/870150/how-to-access-static-resources-when-using-default-servlet/3593513#3593513 – BalusC Jul 30 '12 at 11:23
  • @BalusC: Looks like a winner, I'll try this out when I get home from work tonight and let you know how it goes! – King Skippus Jul 30 '12 at 21:01
  • I'm going to go ahead and mark this answer, although it was really Balus's comment that steered me to the solution I eventually used. – King Skippus Dec 28 '12 at 20:15