views:

723

answers:

4
+2  Q: 

Mask urls in JSP

Related to this question: URL characters replacement in JSP with UrlRewrite

I want to have masked URLs in this JSP Java EE web project. For example if I had this:

http://mysite.com/products.jsp?id=42&name=Programming_Book

I would like to turn that URL into something more User/Google friendly like:

http://mysite.com/product-Programming-Book

I've been fighting with UrlRewrite, forwarding and RequestDispatcher to accomplish what I want, but I'm kind of lost. I should probably have a filter for all http requests, re format them, and forward the page.

Can anyone give some directions? Tips?

Thanks a lot.

UPDATE: Servlets did it. Thanks Yuval for your orientation. I had been using UrlRewrite, as you can see at the first sentence of the question I also asked a question about that. But I couldn't manage to get UrlRewrite work the way I wanted. Servlets did the job.

A: 

It's been a while since I mucked about with JSPs, but if memory serves you can add URL patterns to your web.xml (or one of those XML config files) and have the servlet engine automatically route the request to a valid URL with your choice of paramters. I can look up the details if you like.

In your case, map http://mysite.com/product-Programming-Book to the URL http://mysite.com/products.jsp?id=42&name=Programming_Book and the user no longer sees the real URL. Also, you can use this more user-friendly URL within your application, as a logical name for that page.

Yuval =8-)

Yuval
It would be great if you could give me more details on the implementation.
Fernando
have a look at http://wiki.metawerx.net/wiki/Web.xml.ServletMapping, it should give you an idea of what I meant =8-)
Yuval
A: 

Generally you're fronting your application with Apache. If so, look into using Apache's mod_rewrite. http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html

Michael Glenn
The application is runnning with JBoss (therefore Tomcat as Web container). UrlRewrite is based on Apache mod_rewrite, but I haven't figured out if it's the right tool for what I'm trying to do.
Fernando
From experience it is best not to rely on Apache for url re-writing. It is great for emergency situations. But changes on URLs should be seen as url life cycles. Since urls are interfaces to your application, then their life cycles are part of the app lifecycle itself. Meaning, they should be managed, documented and versioned as part of your application. When you start putting interface changes outside off your application src and config and into Apache, you run the risk of accumulating untraceable changes over time. Design or retrofit your application so that it can handle URL changes.
luis.espinal
But if you go that way, there should be no problem front-facing JBoss with Apache (via mod_jk).
luis.espinal
+2  A: 

You could use a URLRewrite filter. It's like how mod_rewrite is for Apache's HTTP web server.

http://tuckey.org/urlrewrite/

"Redirect one url

<rule>
<from>^/some/old/page\.html$</from>
<to type="redirect">/very/new/page.html</to>
</rule>

Tiny/Freindly url

<rule>
<from>^/zebra$</from>
<to type="redirect">/big/ugly/url/1,23,56,23132.html</to>
</rule>

"

tegbains
A: 

For one thing I'd recommend you deal with this within your application, and not rely on external rewrites, say via Apache mod_rewrite (unless you have determined this is the fastest way to do so.)

But a few things first:

I would not convert this:

http://mysite.com/products.jsp?id=42&amp;name=Programming_Book

Into this:

http://mysite.com/product-Programming-Book

See, if I go only by your book example, I don't see what is wrong with the former URL. After, all it works for Amazon. And there is no such thing as google friendly URLs (only user friendly.) You have to consider why you want to do that type of rewriting, and how. For example, in your rewrite option, where is the id?

That is, you have to define a logical rule that define

the unique pages you want to show, and the unique combination of parameters that can identify each page.

For example, using your book case. Let's say you can identify any book using the following rules:

  1. by ISBN
  2. by Author Name, Title and if applicable version (if version is missing, assume latest)
  3. if ISBN is included with Author Name, Title and/or edition, ignore all except ISBN. That is, treat it as the former (or more precisely, ignore all other book identification parameters when ISBN is present.)

With a ?parametrized url scheme, then you'd have the following possibilities:

http://yoursite/products?isbn=123465
http://yoursite/products?author=johndoe&amp;title="the cookbook" << this assumes the latest edition, or 1 if first.
http://yoursite/products?author=johndoe&amp;title="the cookbook"&edition=3
http://yoursite/products?title="the cookbook"&author=johndoe
http://yoursite/products?edition=3&amp;title="the cookbook"&author=johndoe
....

and so on for all combinations. So before you look for a technical implementation, you have to think very carefully how you will do it. You'd have to create a syntax and a hierarchy of parameters (say, author will always come before title, and title will always come before edition).

So you'll end up with the following (using the same example as John Doe the author, with his book being in the 3rd edition):

http://yoursite/product/isbn/12345
http://yoursite/product/author/johndoe/the%20cookbook << see the %20 for encoding spaces (not a good idea, but something to take into account)
http://yoursite/product/author/johndoe/the%20cookbook/3

Any other combination should either generate an error or smartly figure out how to rewrite to the "cannon" versions and send a HTTP 3xx to the client with the appropriate URL target.

Once you have ironed those details out, you can ask yourself it the effort is worth it or necessary.

So if you find yourself that you need to, then easiest and cheapest DIY way is to write a filter that parses the url, breaks the parameters down, creates a ?parametrized url string for a JSP page, get its RequestDispatcher and forward to it.

You do not want to do URL rewrites because these incur in HTTP 303/307 back and forth between your server and your client. Or at least you want to keep that to a minimum.

luis.espinal