Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I dispatch to WEB-INF with /* servlet-mapping?

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!

like image 470
King Skippus Avatar asked Nov 14 '22 01:11

King Skippus


1 Answers

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.

like image 146
axtavt Avatar answered Dec 15 '22 06:12

axtavt