Using JSP with Jersey JAX-RS Implementation

This post shows you some tips you’ll likely need to use JSP with Jersey in typical Java webapps.

Tested Conditions

While Jersey 1.1.1-ea or later is probably the only hard requirement for the tips to work, my development environment is listed here for your info. You are welcome to add to this rather meager basis for sanity.

  1. Jersey 1.1.1-ea
  2. Tomcat 6.0.20
  3. JDK 1.5
  4. OS X Leopard

Change JSP Base Template Path

Default base path for templates is the root of the webapp. So if my webapp is at “/…/webapps/myapp” then Viewable(“/mypage”, null) will map to “/…/webapps/myapp/mypage.jsp”

To change this, say to “WEB-INF/jsp” as it’s commonly done for security reasons, add following init-param to Jersey servlet/filter in web.xml:

<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/WEB-INF/jsp</param-value>
</init-param>

Return Viewable as part of Response

It was not obvious to me (doh) where Viewable fits into Response when I have to return a Response instead of Viewable. It turns out, Viewable can be passed where message body entity is passed. Example:

return Response.ok(new Viewable("/mypage", model).build();

Use “/*” as servlet-mapping for Jersey

The primitive servlet-mapping URI pattern scheme, which somehow survived many iterations of the servlet API, impacts JAX-RS hard if servlet-mapping is overly broad. Unfortunately, pretty restful URL calls for servlet-mapping to be “/*” instead of something like “/jersey/*”, breaking access to JSP files as well as static resources.

To work around, you’ll have to use Jersey as a filter instead of a servlet and edit a regular-expression init-param value to punch passthrough holes in Jersey’s routing scheme. To enable this, replace Jersey servlet entry in web.xml with something like this:

<filter>
 <filter-name>jersey</filter-name>
 <filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
 <init-param>
  <param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
  <param-value>/(images|js|styles|(WEB-INF/jsp))/.*</param-value>
 </init-param>
</filter>
<filter-mapping>
 <filter-name>jersey</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

That’s all for now. Hope this post saved you some headaches.

Advertisements

Java Cloud

Still undecided about deployment strategies, I looked around to see if there are solutions like Aptana Cloud for Java, preferably with Eclipse support. Unbeknownst to me, Java cloud support started to bloom while I was busy wriggling over SafePage’s fate late last year.

Notables are Stax Networks (TechCrunch mention) which is a service (just got the invitation code) and CloudTools, an open source tool by Chris Richardson of Cloud Foundry that makes it as simple to deploy a webapp cluster as writing a Groovy script. A common trend I noticed is moving away from using AMI as unit of change to using script to modify base AMI image on the fly. Also RightScale’s CentOS 5 AMI image called RightImage seems to be quite popular.

Are there any other Java cloud services or open source projects I overlooked?

Update: Stax uses a command-line tool with a handful of webapp template types to create and deploy. I’ll have to dig in deeper into templates to see how flexible it is.

Update 2: g-Eclipse also looks interesting. I am going to dig into 1.0RC1 release last month and play with EC2 and S3 connectors. I also found Typica and jets3t which can be used to build a custom cloud deployment tool in Java if need be *eyeroll*.

Update 3: My conclusion for the day is that Aptana Cloud stands alone as end-to-end solution so far although others are catching up fast. Note that Aptana Cloud is essentially a cloud reseller, focusing more on development and initial launch phases of startup where companies like RightScale seems to be focusing more on post-launch operational headaches.