Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Servlet path mapping and relative URLs

 
John Russell
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I understand that using a relative URL as the value for an HTML href attribute is usually considered A Good Thing To Do. However, is there a way to make relative URLs work reliably in combination with servlet "path mapping"? Here's a problem situation...

MyServlet produces an HTML page that uses a relative URL to locate a stylesheet, like this:

<link type="text/css" href="style/plain.css">

The web.xml for myapp uses path mapping, like this:

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet/*<url-pattern>
</servlet-mapping>

The problem is that sometimes the browser can find the stylesheet, and sometimes it can't, depending on what URL is used to connect to the servlet.

If you point the browser to http://localhost:8180/myapp/Servlet1, the stylesheet can be found. With that base URL, the relative URL style/plain.css points to http://localhost:8180/myapp/style/plain.css, which is where the stylesheet really is.

However, if you point the browser to http://localhost:8180/myapp/Servlet1/ (note the trailing slash) the stylesheet is not found, because the relative URL then points to a non-existent location, http://localhost:8180/myapp/Servlet1/style/plain.css

Eventually, I resorted to constructing an absolute URL for the stylesheet, using code like this:

URL x = new URL( req.getRequestURL().toString() );
String href = x.getProtocol() + "://" + x.getHost() +
":" + x.getPort() + req.getContextPath() +
"/style/plain.css"

That worked, but was it necessary? Are there other ways to handle it? Any thoughts will be much appreciated.

John
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 64824
86
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by John Russell:
I understand that using a relative URL as the value for an HTML href attribute is usually considered A Good Thing To Do.


Not on my particular "Good Things" list.

Using relative URLs pre-supposes realtionships between the files, which creates an artificial binding between them.

I always use server-relative URLs for resource references and avoid any such problems.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 64824
86
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Eventually, I resorted to constructing an absolute URL for the stylesheet


The URL doesn't need to be absolute, but server-relative as I said above.

For example:

/context-path/images/whatever.jpg


If you are doing this in a JSP, the <c:url> tag is your best friend. If you are doing this in a servlet.... well, why would you be generating markup in a servlet?
[ February 07, 2006: Message edited by: Bear Bibeault ]
 
John Russell
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Bear! The server-relative URL works great! And your explanation about the downside of page-relative URLs helped dispel my prejudice about them.

By the way, I encountered another, unrelated problem that sometimes prevented the stylesheet from taking effect. That problem was corrected by adding rel="StyleSheet" to my link element. (Thanks to Google and http://www.htmlhelp.com/reference/html40/head/link.html) Combining that fix with your fix, the working HTML now looks like this:

<link rel="StyleSheet" type="text/css" href="/myapp/style/plain.css">

The servlet code that generates the href value is this:

String stylesheetURL = req.getContextPath() + "/style/plain.css";

I have no strong reason to generate the HTML in a servlet. I look forward to learning more about <c:url>. Thanks for the tips!

John
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic