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!