First, read the chapter about Web Applications in your SE User Guide.
Then play around with the exampleWebApp that comes with SE (described in the guide).
You should also be aware of how easy it is create an empty webapp structure using the SE admin UI.
See the HINT at the bottom of SE FAQ #137.
You can then begin populating that empty app with the components of your application.
Each webapp has it's own private document root.
Your code can learn where (on the hard-drive) that is by using the techniques given in
SE Interest List posting #84990.
And one of the most common stumbling blocks for people who are new to webapps is the
notion of a context path and what that means to the browser.
Here's an example to help illustrate this:
- You have a webapp whose context path is /myWebapp
- You request http://myHostName/myWebapp/myPage.html
- myPage.html emits a link that looks like this
<a href='/myOtherPage.html'>click here</a> (a page sitting right next to myPage.html)
- When you click on the link, the browser requests http://myHostName/myPage.html (Note that the context path is now missing), and you get a 404 - not found response.
In the above example, myPage.html is a static page (not a JSP, or a servlet) and so it's links are hard-coded.
This is fine as long as the context path portion of the hard-coded link matches the context path of the webapp
to which the page belongs (or... from which the page was served).
But if it does not match, then you run into this problem.
There are a few solutions... you could change the context path of your webapp to be just a single forward slash "/".
Or you could edit myPage.html. Or you could rename it to myPage.jsp and use the following sort of code to programatically prepend the right context path:
String cp = request.getContextPath();
cp = "";
<a href='<%=cp%>/myOtherPage.html'>click here</a>
If you have many such links then instead of prepending the context path to each and every URL another option would be to use the BASE element to standardize the location to which relative URLs are resolved by the browser. For example:
You could also just use:
<a href='myOtherPage.html'>click here</a>
But that won't likely work for links emitted by a servlet since the request URI to invoke a servlet typically involves the use of an alias... which does not map to an actual, physical place on the hard-drive.
You request http://hostname/myWebapp/servlet/MyServlet (a servlet inside your webapp) which returns HTML markup that tries to reference a CSS page (or basically just some physical file inside that very same web application).
The servlet will need to prepend the context path of the webapp to the link... it can't just use "my.css" as the link (even if my.css is sitting right in the root of your webapp).
This is because the browser knows that it just requested /myWebapp/servlet/MyServlet
If it then tries to resolve "my.css" (a relative URL) it will do so relative to where it thinks the page was served.
So it will try to get http://hostname/myWebapp/servlet/my.css which will cause SE to say "Failed to get Servlet... There is no servlet named my.css... ClassNotFoundException" or some such message.
The use of
request.getContextPath() above, obviously requires that a request object be available. So that solution can only be used at request-time, by methods that have access to the request object. A more elegant approach would be for your application to learn its own context path at the time it initializes (before any request has arrived). Beginning with Servlet API Specification 2.5 (implemented by SE 6.0) this is possible via the ServletContext.getContextPath() method. If you know your app will only be used on Servlet 2.5 compliant Servlet/JSP Engines then you could use this technique at webapp init time and "cache" the result in the application scope.
Other code that needs it could then look it up from that scope.
Another option would be to use the URL tag provided in the JSTL since that tag takes care of prepending the proper context path automatically. Of course that option only works for JSP pages.
If your webapp code needs to know the physical path on the hard-drive to which it has been deployed then you could use this code:
String appRoot = application.getRealPath("/");
NOTE that for webapps deployed in .war file form, ServletExec will expand the contents of the .war file to a "working" folder, so appRoot in that case will be the absolute path to that "working" folder.
Readers of this FAQ may also benefit from reading SE FAQ #278