5
votes

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!

1
remove the /WEB-INF from the request and checksreejith
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
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 requestssreejith
/* takes everything from your context-path and also WEB-INF is part of it.chaosguru
also which framework are you using for MVC?chaosguru

1 Answers

1
votes

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.