How to build robust relative links in Servlet and JSP applications.
First, the difference between a relative and an absolute link. Assuming you have a plain old HTML page my-page.html in the root directory of your web server. Let's also assume that you also have and images directory under the root directory of your web server and the image you want to link to is in that directory.
If your domain is my-domain.com the URL to this page will look like this
If you have an image in your images folder that you want to display in your page, the absolute link to that image would look like this
This is absolute because it contains all the information that a browser would need to find it on the web. A sure fire way to make sure it will work in your page is to use this full and absolute URL in your image tag:
This is simple, no matter where your HTML page is within your app, the link will work. It would even work if your image were linked to from another HTML page, in another app, in another server!
So why doesn't everyone just use absolute links? Domains change.Many sites are built on local machines using just the IP number or localhost as the domain. Most good size websites will have hundreds or thousands of link tags and changing all of them every time the site is moved is cumbersome and error prone.
Introducing Relative Links
Since the browser already knows what the domain and path are for the current HTML page, it makes sense to be able to use a path in your tag that is relative to the location of that page.
In this case the browser will look for an image under an images directory under the same domain and path as the HTML page in which the link is contained.
What if your HTML page is nested several directories from the root of the web site? Suppose your page is under x/y/z/my-page.html and you still want to use the image under the images directory? Can you still use a relative link or do you now have to use an absolute link?
There are two ways to use a relative link in this case. The first is to use the .. operator which means 'one directory up'
This says to look 3 directories up for a directory named images, then look for my image in there. This can get ugly. Like with absolute links, you would have to fix all of the paths if you changed the structure of your webite.
Linking relative to the root of your site
Another approach is to use a path that is relative to the root of your site. You can do this by prepending a forward slash to the relative link.
This tells the browser to look for this image under the given path but relative to the root of the application (right after 'www.my-domain.com/). It doesn't matter where your page is within the app.
This is probably the most sound way to build links in an HTML site. You can now move the entire site to a different domain. You can move and restructure the HTML pages without having to change all of the links to the images (providing you don't move the image directory).
What's different for servlet and JSP apps?
All of the above applies to static HTML websites and will work with any HTML/1.0 or HTML/1.1 compliant browser.
There something unique about Servlet and JSP apps that can throw a wrench into the gears. This is called the Context Path.
Servlet/JSP containers can house multiple webapps under one domain. This is a great feature in J2EE. It lets you bundle and deploy entire applications as a single 'war' file. It also allows different components within an app to share objects in memory but without exposing them to other applications running in the same container.
In order to differentiate between the different webapps running under the same domain, the container looks at the first 'directory' after the domain name. This is called the Context Path.
If the name of your app is 'my-app' and your page is 'my-page.jsp' the url would look like this:
All of what we've talked about so far still applies except the location of the site's root directory (from the browser's standpoint).
The root of your site, as far as the browser is concerned is still
but within the Servlet/JSP environment the root of your webapp is
Links relative to your page will still work. You can also still use the messy .. syntax to look in directories higher than your page. What you can't do is build a link relative to the root of your site the way we showed you earlier.
Another great benefit to J2EE apps is that you can map servlets and JSP pages to whatever url-pattern you like from within your web.xml file.
This brings us back to the dilema of choosing between the .. syntax and hardcoding the context path into every link in the site in order to use relative links. The problem with hard coding the context path is the same as the problem with absolute links. Every link will need to be altered if the context path changes and context paths change a lot.
Often webapps will move from dev to qa before being moved to production. This can easily be done within one container by changing the context path. (my-app-dev, my-app-qa, and then just / for production)
The getContextPath Method
Using the getContextPath method in servletRequest, we can determine the context path for your application at run time.
From within a Servlet
In a JSP 1.2 app with JSP Scriptlet Expressions
In a JSP 2.0 app using EL
You can now move your entire application from domain to domain without having to alter each link. You can also rename the webapp and run multiple copies under one container and still not have to alter the path for your images.
However, links in HTML files (if any) need to be changed manually whenever the context path changes.