views:

695

answers:

5

Hey there,

I'm planning on starting a web project, and I've been searching for the best option. Ultimately I choose to stick with Java + Seam + J Boss AS + JPA Hibernate.

But regarding URL Rewriting its been a really long run, without many accomplishments.

I'll have a hierarchical structure, Ex. Category -> Sub-category -> Sub-sub-category.

Basically I want these to map like foo.com/category/sub-category/sub-sub-category

  • What helps me accomplish this?
  • What are other possibilities?
  • How flexible is URL rewriting?
  • Can I append non-hierarchical data into my url? Ex.. .../category/sub-category/type/sub-sub-category

My questions regarding flexibility are mainly because, RESTFUL is supposed to be core. So if URL rewriting isn't that flexible, I'll have to carefully think about my design.

Regards.

+1  A: 

I use Restlet to handle the mapping of resources. I've not tried it with Seam, but I understand they fit well together.

Update: Someone has created an example project showing how to integrate them and an associated forum post.

The Restlet 2.0 Tutorial describes how to handle URL rewriting and redirection.

Rich Seller
+1  A: 

URI construction is orthogonal to REST. See: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Wahnfrieden
Indeed. Rather than calling such URIs "RESTful" one might call them "cool URIs" (an asinine name--but an established, correct one).
+1  A: 

What about other options for url rewriting?

Prettyfaces?

http://ocpsoft.com/prettyfaces/
Lincoln
+1  A: 

You can use Seam's inbuilt URL rewriting, or if you'd like more flexibility in the rewrite rules, you can use the UrlRewriteFilter from http://tuckey.org/urlrewrite/. Examples of both below:

Seam's inbuilt rewriting (which prob uses the tuckey filter under the covers anyway)

First enable the url rewriting in the components.xml file

<web:rewrite-filter view-mapping="*.seam"/>

Next, add the rewrite rules to the pages.xml file

<page view-id="/home.xhtml">
    <rewrite pattern="/home/{category}/{sub-category}/{sub-sub-category}" />
</page>

In this case, an incoming url served as

/home/vehicles/cars/fords

Will be served as if it was a request for

/home.seam?category=vehicles&sub-category=cars&sub-sub-category=fords

In the same way, outbound url's will be converted if the page has the named request params available.

Or you could use the Tucky UrlRewriteFilter as follows

Add the Tuckey UrlRewriteFilter jar to your project which you can grab from here

http://tuckey.org/urlrewrite/

Next add the filter your your web.xml file

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

Finally add a file called urlrewrite.xml to your WEB-INF dir. This file will define your rewrite rules. You will probably want to be somewhat familiar with regex. The file should looks as follows

^/home.seam?category=(.)&sub-category=(.)&sub-sub-category=(.*)$ /home/$1/$2/$3

<rule match-type="wildcard">
   <from>/home\/$1\/$2\/$3</from>
   <to type="redirect">/home.seam?category=$1&sub-category=$2&sub-sub-category=$3</to>
</rule>

Seam doco is here - Seam documentation

Tucky UrlRewriteFilter doco is here - Tuckey RewriteFilter doco

Aaron Chambers
Looks like the markdown parser doesn't like my regex expressions ;) Infact it stripped out a whole bunch of text. I'll add it to another comment
Aaron Chambers
Aaron Chambers
A: 

I am using the same frameworks you are planning to use (Java + Seam + J Boss AS + JPA Hibernate), and also RestFul webservices are my core. I choose resteasy as the rest frameworks and it works just fine and easy (both to rewrite and to test, same as easymock). Also it is a jboss product and works fine with seam, easy to integrate. As a sample code:

@Path("/webservice")

public class Web {

@GET
@Path("{web}")
@ProduceMime("application/xml")
public String test(@QueryParam("param") String param, @PathParam("web") String web)

{ // code here } }

  • @Path is your "root path" of the class (your real "root" would be configured on components.xml)
  • @GET is from Rest
  • ProduceMime or ConsumeMime is the mime you should consume or produce
  • @QueryParam is the params of the url and @PathParam the parameters you should get

So this get will receive a call from /webservice/web?param=lalala and return a string in the application/xml format

Diego Dias