Login

Apache Tapestry 4 Tutorial

In this article we’ll begin by taking a look at servlets and JavaServer Pages, then proceed to learn about the MVC design pattern. After examining the problems these technologies solved, we’ll focus on the Tapestry framework, study its advantages, and dispel some prejudices about it. This is the first article in a multi-part series covering Tapestry.

In the beginning, there were servlets.

A servlet is basically a piece of Java code written in such a way that it can run on a server on the Internet. Servlets live in a so-called servlet container that handles all the low level issues, allowing the servlet author to concentrate on what exactly he or she wants to do.

Servlets are a foundation of every Java Web framework. Struts, JSF, Tapestry – all of them have at least one servlet, at the very least as a gateway between the world of Java and the world of Web.

However, in the early days of Java Web development there were no frameworks, only servlets. And if a developer wanted to display a dynamically created HTML page, he or she would have to print out HTML inside of Java code like this:

out.println("<table border="1" cellpadding="5" width="500">");

Now imagine that your page is a decent size, say, a hundred lines of code. You will have to write a hundred statements like this one. You can easily forget to escape one of those quotation marks or make some other error so that the servlet will not compile. This means the code is very fragile.

But say you managed to do everything properly and your servlet compiles and works just fine. Now your designer decides to change something on the page. Being a true Java programmer you might have no idea about HTML and styles, and your designer certainly has no idea about Java. So who will make the change? This means the code is difficult to maintain. Also, any minor change in the page contents or design will require recompilation of the servlet.

Although the servlets are powerful and efficient, they are not that good when it comes to rendering a dynamic HTML page. Some other solution was needed.

{mospagebreak title=JavaServer Pages came to the rescue}

Technically, a JSP page is just the same servlet as it gets compiled into a servlet behind the scenes before it is shown to a Web application’s user. However, from the developer’s point of view, working with JSP pages is a completely different thing. You can have as much HTML in your page as needed, and if you want to use some Java code, you just insert a scriptlet, as in this example:

<p>Some nicely formatted HTML goes here</p>

<%

// And here is some Java code as needed by the page

String name = request.getParameter("firstName");

%>

<p>Hello <%= name %></p>

This was the original design of JSP technology. What can be better: designers can work on their pieces of HTML, Java programmers can work on their pieces of code, and whatever is generated in the code can be easily inserted into HTML using a simple notation.

But this holds true only for simple pages with limited functionality. As the dynamic part of the page becomes more complex, Java unavoidably gets mixed with HTML. Have a look at another example:

<%

for (int i = 1; i <= metaData.getColumnCount(); i++) {

if (metaData.getColumnType(i) == Types.DOUBLE) {

%>

<td align=’right’>

<%= formatter.format(resultSet.getDouble(i)) %>

</td>

<%

} else {

%>

<td>

<%= resultSet.getObject(i).toString() %>

</td>

<%

}

}

%>

If you write such a page yourself and you know both HTML and Java, no problem, you can do this. However, many Java Web applications are created by a group of people, often with narrow specializations, and this kind of Java/HTML cocktail makes both designers and developers unhappy.

As a result, it was decided that scriptlets are a bad thing, and they should not be used. Instead, a set of tags was provided. If designers don’t like Java code, they should be much happier working with tags.

The idea was to have all Java code in some separate Java class, referred to as a bean, and then you can use that bean from your JSP page by using a few simple tags like these:

<jsp:useBean id="myBean" class="com.example.MyBean"/>

Hello <jsp:getProperty name="myBean" property="firstName"/>

Again, the idea wasn’t bad, especially for simple pages. But for anything more complex the existing set of tags was severely limiting.

Of course, there was an opportunity to write your own custom tags and do in them everything you can imagine. But writing custom tags isn’t for the fainthearted; one would need a pretty good understanding of the details of JSP technology to do that. Also, if you wanted to output some HTML in your custom tag, you would have to print it out in the same way as in a servlet.

Still, many developers produced numerous libraries of custom tags, and one such library, JSTL (JavaServer Pages Standard Tag Library), became a part of JSP standard.

However, obstinate developers kept using scriptlets in their JSP pages, saying that even the best custom tags do not give them the flexibility they require. This finally led to yet another addition to JSP – the Expression Language (EL).

Expression Language is truly powerful and convenient. The only problem is that to get rid of Java code inside of JSP pages, three different notations were introduced: standard tags, custom tags and EL expressions. All three have slightly different logic, naming scheme and rules, so that learning them in detail can be quite a nuisance! Have a look at this brief example, taken from real life code:

<tr>

<c:forEach var="column"

items="ID,Name,Quantity,Price,Total">

<th><c:out value="${column}"/></th>

</c:forEach>

</tr>

Does this look like a clean separation between HTML and code? I wouldn’t say so.

Still, JavaServer Pages technology solved the tasks for which it was created. However, this is a rather low level technology. Creating a Web application from scratch using JSP pages and servlets required writing a lot of "boiler plate code" again and again, or copying and pasting large chunks of code – what a reliable source of hard to find errors!

Some kind of framework was required that would have all the basic stuff already written and would provide some sort of architectural solution for a future Java Web application. A number of such frameworks appeared; the most famous of them is Apache Struts. Typically, they embodied the MVC (Model-View-Controller) pattern, widely regarded as a panacea for many problems of software development.

{mospagebreak title=The Holy Trinity of software development}

The main aim of MVC design pattern is to separate the business logic and data (the Model) from the display logic (the View).

Ideally, the Model should have no idea of what displays its data (and how that data is displayed) as there can potentially be numerous different views. The View in its turn should have no idea of where the data it displays come from, as data can potentially come from just anywhere.

It is for the piece of code named Controller to ensure that a correct piece of data was sent for processing to the Model and that the result of that processing was forwarded to a proper view.

Struts and similar frameworks came with their own views, typically implemented as JSP pages, and their controllers, implemented as Action classes. As for the model, it is implemented elsewhere – maybe as an Enterprise JavaBeans application or perhaps something more lightweight.

Struts have also provided a number of convenient solutions for the most common tasks of Web development, and as a result, this framework became enormously popular. Currently, Struts is a de facto standard of a Java Web framework. However if you follow the trends of the Java world, you might know that although Struts is the present of the mainstream Java Web development, it is not widely considered as its future.

The main problem with Struts is that it is still a somewhat low level solution. It still leaves the developer writing a lot of code, and often that code solves some basic repeating tasks. The future belongs to component-based frameworks because with them one could write much less code and encapsulate significant pieces of logic into easily reusable components. At the extreme, a component-based framework could allow developers to simply assemble a web application from the existing components, only changing a few parameters of those components as required.

The other downside of Struts is that it uses JSP for its views. Yes, one could use a different display technology, such as Apache Velocity, but JSP is the default and the most widely used option, with all its inherent weaknesses.

In fact, one can still use scriptlets in Struts views, and many developers do use them because this looks to them like a simpler solution. The later versions of JSP even have a special setting that allows programmers to ban the use of scriptlets in the application – an administrative measure in software technology!

Also, although seasoned Struts developers will probably disagree with me, Struts introduces a rather unnatural view of a Web application. Normally – say, for users – a Web application looks like a set of pages. They read the content of a page or play with it, then go to another page and so on. From the Struts point of view however, a Web application is a set of actions that users initiate. Pages are only the results of those actions.

This doesn’t seem like a huge issue, but from my point of view, this action-centered thinking makes it difficult for many Struts developers to understand a newer framework – more about this later.

So what do the new component-based frameworks bring with them? Most significantly, a sharp increase in development productivity. My current rough estimate is that one week of Tapestry development is approximately equal to one month of Struts development, in terms of which part of the whole project gets completed in this time. And the more projects are built by the team, the less time the next project will take, just because of reuse of already created custom components.

Also, simply because less code is being written, the applications developed with new frameworks have less errors and are easier to maintain.

I would say that the three most widely known contemporary component-based Java Web frameworks are JavaServer Faces (with its different variants), WebWork and Tapestry. Comparing them all clearly goes out of the scope of this article (I have written a whole Masters dissertation on this; have a look if you are curious: http://sundraw.ws/assets/TapestryDissertation.pdf), so let me simply explain why my choice is Tapestry.

{mospagebreak title=Why Tapestry?}

The First Reason: Tapestry is easier to learn than any other contemporary framework. I hope you will appreciate this following my tutorials. This is because the higher level architecture of Tapestry is natural and clear. Every page of a Tapestry application is a Java class. It can have its state – properties – and its behavior – methods. Pages can handle different events as they have event listeners for them.

This sounds very familiar to everyone who has done object-oriented programming, regardless of programming language. This is why Tapestry should be easy to adopt by a wide range of programmers coming from different platforms. In fact, my colleagues with an ASP.NET background find Tapestry easy to understand – but not Struts.

The Second Reason: Tapestry has a unique display technology. For example, with JSP, when you take an HTML mock up and convert it to a dynamic page, this process is irreversible. Something, which was only recently a design masterpiece, becomes, at least from the designer’s point of view, a bunch of incomprehensible tags. And if there is any significant change in design, it might be simpler to throw away the existing JSP page and to create it anew.

Let’s consider an example. Here is how a designer would create a simple text box:

<input type="text" class="someStyle"/>

To make this text box a dynamic part of his application, a Struts developer would write something like this:

<html:text property="userName" styleClass="someStyle"/>

And here is the same work done by a Tapestry developer:

<input type="text" class="someStyle" jwcid="userName"/>

The difference is obvious: the Tapestry template remains a valid HTML page and can be easily previewed by any standard tool, or any Web browser. To convert an HTML element into a Tapestry component, all we need to do is insert a special jwcid (Java Web Component ID) attribute. Any piece of software that doesn’t know what this attribute means will simply ignore it.

One of the benefits of this is that a Tapestry template remains perfectly editable by any design tool, without a danger of breaking any Tapestry instrumentation. You will appreciate this when, after creating a few dozen pages for the first iteration of your project, you receive feedback from your client saying that design and layout should be changed in, say, 36 places. With Struts, that would be a disaster. With Tapestry, this is no problem at all.

Also, if you start your project from a series of HTML mock ups created by a designer, it takes very little effort to convert mock ups into Tapestry templates.

All in all, the Tapestry’s unique display technology makes Java Web development much more efficient and solves the problem with which JSP technology has been struggling for years.

The Third Reason: Tapestry custom components are very easy to create and use. Again, Tapestry is unique in this respect between contemporary component-based frameworks. For example, in JavaServer Faces to create a component you need to know intimately the inner (quite complicated) structure of the framework. This is a task for an advanced developer, not a beginner.

In Tapestry, we shall start creating custom components in one of the first parts of this tutorial and you will see how easy it is. As soon as you see a repeating piece of the interface or functionality, you just put it into a component and then drop that component onto any page where it is needed. If you think that your components will be useful in a different project, or maybe you want to make a present for your friend, you can easily pack them into a library and distribute as widely as you wish.

This is especially important because, as perhaps is true with every framework, Tapestry has some obvious simple components missing. But that is no problem at all – create them yourself and share them with the others. This is one of the things we are going to do later in this tutorial.

The Fourth Reason: Tapestry has in it just everything one would expect from an advanced contemporary framework. A superb, easy to use user input validation, internationalization, incomparable error reporting, version 4.1 has its own AJAX components, version 5 goes even further in terms of efficiency and beauty of design… What else do you want?

So, if Tapestry is really so good, why it is not as popular as it deserves to be? This is actually a surprise for me. After spending so much effort to convince my manager that Tapestry is the right tool for our next project I feel like there is some kind of psychological barrier surrounding Tapestry. My opinion is that there is a set of prejudices that hinders Tapestry’s advancement. Two of them are listed in the next section.

{mospagebreak title=Tapestry and prejudices}

Prejudice 1: Tapestry has a steep learning curve.

Well, it does, in some sense. But the only reason for this steepness is that Tapestry’s documentation is incomplete and there are very few sources of information about it.

In fact, the only book on Tapestry that I would wholeheartedly recommend is "Enjoy Web Development with Tapestry" by Kent Tong (http://www.agileskills2.org/EWDT/index.html). This book helped me enormously when I was learning Tapestry 3; it is regularly updated, so now it is available for Tapestry 4.1. You can download the first four chapters of this book for free.

In order for a software solution to become popular, a number of different sources of information are needed, written in different styles, and this is what Tapestry is missing. The book by Kent Tong is excellent, but it is very concentrated, and many people might find it hard to read and follow. I feel like a gentle introduction to Tapestry is needed, with plenty of time spent discussing different things and looking at them from different sides. And this is what I am going to create here.

Prejudice 2: Tapestry is just another MVC framework. Why would we need yet another one when we already have Struts?

This is completely wrong, as Tapestry is very different. It is much more advanced than Struts. If my reasoning in the previous sections didn’t convince you, try to follow the coming chapters of this tutorial and see if they can do something for you.

In fact, I find that Tapestry can be most difficult to understand for experienced Struts developers. This is because they are used to the peculiar Struts way of doing things and to the fact that there are several frameworks out there which are simply variations of the Struts approach.

So a Struts developer, looking at Tapestry, tries to find some version of Action classes, familiar views and controller, some tags to stuff them into views, some extensive configuration files… There is even a book that tries to follow this approach ("Art of Java Web Development" by Neal Ford), but the result is just a misunderstanding.

I think it might be important to understand that to achieve a clean separation of concerns, there is no need to literally embody the MVC pattern by putting all views into one room and all code into another room, and then writing an extensive configuration to keep track of them all. Tapestry is a good example of a creative and successful alternative approach to the problem. Its templates are similar to views, its page classes are similar to controllers…

But you are definitely fed up with theory for now, aren’t you? Let’s go to practice then.

What comes next?

First of all, we shall need to have a working configuration of a few pieces of software that will enable Tapestry development. In fact, this configuration will be more or less the same as for any other kind of Java Web development: a Java Development Kit (JDK), an Integrated Development Environment (IDE) and a servlet container.

The most popular approach is to use Eclipse as an IDE and I will give some pointers on creating an Eclipse-based configuration. But I have found that NetBeans IDE can provide an even shorter path from installation to deployment, so I am planning to make NetBeans the main tool for this tutorial. I know that there is a Tapestry module for NetBeans being developed, and we are going to adopt it at some point.

We shall have a look at the standard structure of a Java Web application and how Tapestry applications reflect it. Finally, we shall build our first simple Tapestry application and discuss how and why it works.