[ Team LiB ] Previous Section Next Section

17.8 How URIs Are Interpreted

One thing that can be confusing in a JSP-based application is the different type of URIs used in the HTML and JSP elements. The confusion stems from a combination of conflicting terms used to describe URIs in the HTTP, servlet, and JSP specifications, and the fact that some types of URIs are interpreted differently in the HTML and servlet worlds.

In HTML, URIs are used as attribute values in elements such as <a>, <img>, and <form>. JSP elements that use URI attribute values are the page, include, and taglib directives and the <jsp:forward> and <jsp:include> actions. JSTL and custom actions can also define attributes that take URI values.

The HTTP/1.1 specification (RFC 2616, with more details in RFC 2396) defines a URI as a string, following certain rules, that uniquely identifies a resource of some kind. A URL is just a special kind of URI that includes a location (such as the server name in an HTTP URL). An absolute URI is a URL that starts with the name of a so-called scheme, such as http or https, followed by a colon and then the rest of the resource identifier. An example of an absolute URI for a resource accessed through the HTTP protocol is:

http://localhost:8080/ora/ch12/login.jsp

Here http is the scheme, localhost:8080 is the location (a server name and a port number), and /ora/ch12/login.jsp is the path.

The URIs in HTML elements are interpreted by the browser. A browser needs the absolute URI to figure out how to send the requests for the resources referenced by the HTML elements. It uses the scheme to select the correct protocol and the location to know where to send the request. The path is sent as part of the request to the server, so the server can figure out which resource is requested. But when you write a URI in an HTML document, such as the action attribute of a form element or the src attribute of an image element, you don't have to specify an absolute URI if the resource is located on the same server. Instead you can use just the URI path:

<img src="/images/hello.gif">

This type of URI is called an absolute path, meaning it contains the complete path for the resource within a server; the only difference compared to an absolute URI is that the scheme and location is not specified. The browser interprets an absolute path URI as a reference to a resource on the server that produced the response, so it adds the scheme and location it used to make the request. It then has the absolute URI it needs to make a request for the referenced resource.

Another type of URI is called a relative path, because it's interpreted relative to the path of the current page. A relative path doesn't start with a slash:

<form action="authenticate.jsp">
<img src="../images/hello.gif"

Here the action attribute references a JSP file at the same level in the path structure as the page that contains the reference. The src attribute value uses the ../ notation to refer to a resource one level up in the structure. The browser interprets a relative path URI as relative to the path for the request that produced the page. If the two relative paths in this example are used in a page generated by a request for http://localhost:8080/ora/ch13/login.jsp, the browser interprets them as the following absolute URIs:

http://localhost:8080/ora/ch13/authenticate.jsp
http://localhost:8080/ora/images/hello.gif

Relative URI paths offer a lot of flexibility. If all references between the web resources in an application are relative, you can move the application to a different part of the path structure without changing any URIs. For instance, if you move the pages from /ora/ch13 to /billboard, the relative paths still reference the same resources.

So far, so good. Now let's see what happens in a Java web container when it receives a request. The first part of a URI for a servlet or JSP page has a special meaning. It's called the context path; one example is the /ora path used for all examples in this book. As described in Chapter 2, a servlet container can contain multiple web applications, handled by a corresponding servlet context. Each web application is associated with a unique context path, assigned when the web application is installed. When the web container receives a request, it uses the context path to select the servlet context that's responsible for handling the request. The container hands over the request to the selected context, which then uses the URI path minus the context path to locate the requested resource (a servlet or a JSP page) within the context. For instance, an absolute URI such as http://localhost:8080/ora/ch13/login.jsp is interpreted by the container as a request for a JSP page named /ch13/login.jsp within the context with the context path /ora.

Because a web application can be assigned any context path when the application is installed, the context path must not be part of the URIs used in JSP elements (and servlet methods) to refer to other parts of the same application. You can always use a relative path URI, just as you do in HTML elements, for instance to refer to another page in a <jsp:include> action:

<jsp:include page="navigation.jsp" />

This type of URI is called a page-relative path in the JSP specification. It's interpreted by the container as relative to the page where it's used. In other words, it's exactly the same type of path as the HTTP specification calls simply a relative path.

Sometimes it's nice to be able to refer to an internal application resource with a URI that is not interpreted relative to the containing page. An example is a reference to a customized error page that is used by all pages in the application independent of where in the path structure they are located:

<%@ page errorPage="/errorMsg.jsp" %>

When a URI in a JSP element attribute starts with a slash, the container interprets it as relative to the application's context path. The JSP specification calls this type of URI a context-relative path. This type of URI is useful for all sorts of common application resources, such as error pages and images, that have fixed URIs within the application path structure.

In summary, a URI used in an HTML element can be:

  • An absolute URI (a scheme and server name, plus the resource path)

  • An absolute-path URI (a path starting with a slash), interpreted as the absolute path to a resource on the server that sent the response containing the URI

  • A relative-path URI (a path without a starting slash), interpreted as relative to the absolute path used to request the response that contains it

A URI used in a JSP element (or a servlet method) can be:

  • A context-relative path (a path starting with a slash), interpreted as relative to the application's context path

  • A page-relative path (a path without a starting slash), interpreted as relative to the path for the page where it's used.

As long as you remember that URIs used in HTML elements are interpreted by the browser, and URIs used in JSP elements are interpreted by the web container, it's not so hard to figure out which type of URI to use in a given situation.

    [ Team LiB ] Previous Section Next Section