RSS feed
<< June 10, 2004 | Home | June 12, 2004 >>

Living la vita JSP.

I have finally seen the JSP light! I think I actually like them and I will have to stop pouring scorn upon them (and all who use them)! So maybe 2004 is a bit late to be blogging about the wonders of JSPs, but the agent of my conversion has been the new JSP 2.0 combined with the latest 2.4 servlet specification. Together with a bit of careful thought, the new features result in a capable MVC web framework directly on a raw servlet container without the need for heavy weight framework like struts.

Living "la vita open source" as I do, I have recently moved to a telecommuting village on the Italian riviera: Colletta di Castelbianco. I undertook to redevelop the village's website, which was a rushed job that needed an internationalised wiki wrapped around a booking engine. As there are too many web frameworks out there to evaluate, I decided to try to do without.

My basic complaint against JSPs has always been that they do not really separate concerns very well. In fact JSPs originally munged concerns into a single file of unreadable HTML and java code together. The later addition of custom tags improved the principal of JSPs, but the practise was still a mess of descriptors, classes and way too much <% } %> going on.

JSP2.0 and 2.4 Servlets have changed all that. They finally provide the features needed to develop parameterized HTML in modules that are well separated from the business and implementation logic. The key new features are:

    Filters: Added in 2.3 and refined in 2.4, Filters allow a form of aspect oriented programming to be used within a webapp. I have used separate filters to capture each of the major concerns of the Colletta site: Internationalisation, Authentication, Navigation, generic POST handling and specific business logic filters derived from the generic POST filter. Filters provide an easy way of adding logic to a webapp, without the need for a Controller servlet and additional configuration mappings. Why have yet another xml descriptor file mapping controllers to URLs when web.xml can now do that for you!
    Expressions: At first glance, JSP expressions look like a bit of a ${novelty + act}. But they provide a vital link between logic and presentation that avoids much boiler plate syntax. Expressions provide a search mechanism that looks up requests, parameters, sessions, context scopes and hides all the null checking, bean methods, reflection and map lookups that may otherwise end up in the JSP. Expressions finally provide an elegant way of parameterising both HTML fragments and calls to custom tags.
    Tag Files: Modularity, encapsulation and reuse can now be had in the presentation layer without the hassle of descriptors, helper classes and bizzare over complex APIs. No more is a tag developer forced to use java for generating reusable HTML. The simplicity of tag files encourages the creation of a tag almost a soon as a single line of HTML is repeated. Development of a set of custom form input widgets is now trivial and the JSP expressions allow excellent parameterisation of the tags.

The Colletta site has been internationalised with a 167 line LocaleFilter. It's initial job is to look at requests and to determine the locale for them, either from the session, cookies set previously or from HTTP accept headers. Once the locale is determined for the request, the input and output encodings are handled and the filter can forward the request to a localised resource. Thus a request for logo.gif may be forwarded to logo_it.gif or logo_en.gif. More importantly, because 2.4 filters can be applied to request dispatches, this filter is in the path of a <jsp:include page="text.jsp"/> and can include text_it.jsp instead. Thus layout JSPs can simply include localised content.

But localisation cannot be done simply by bulk includes of content. Thus the PageFilter uses the locale and the requested resource to select a localised property file for the request (eg page_it.properties in the same directory as the requested resource). The resulting property files is combined with those from all ancestor directories, cached and set as the "prop" attribute on the request. The presentation JSPs can thus access localised properties via JSP expressions like ${prop.name}. This allows simple localisation of complex layouts and error messages without making the HTML unreadable.

As a final example, I will show you the JSP code that renders the discount field in the booking form:

  <td ...>
    ${prop.discount}:
  </td><td ...>
    <tag:curInput 
      name="discount"
      value="${reservation.discount}" 
      readonly="${!user.managerOf[reservation.aptId]}"/>
  </td>
This input field is preceded with a localised label and then calls the tag file for currency Input to render the actual HTML input field. It is passed the current value of the discount from the reservation option that the BookingFilter has put in the session. Also passed is the readonly flag that is true if the current user (placed in the request by the UserFilter) is not the manager of the apartment. The power here, is not in the tag file (whose details I leave to your imagination), but in the way that JSP expressions allow complex data derived in separate logic to be combined and passed to parameterise modules of HTML.

Web frame works - who needs them!