The Web Framework Evaluation - Part 03

In this article series, we are going to explore web frameworks from a Java point of view. It covers Java based frameworks and frameworks based on scripting languages that can run inside of a Java application server. The latter are for example Ruby, Python, PHP, Groovy based frameworks.� This article is taken from my eBook 'The Web Framework Evaluation'.

You can get the eBook at http://www.laliluna.de/shop.

Difference between the free article and the eBook in PDF format.

Defining evaluation criteria

Every evaluation needs a set of evaluation criteria. This is a complex process. In a first step, a fantastic brainstorming will create a long list of requirement, then they have to be grouped and ordered and finally we need to weigh them. Which requirement are more important then others? I have done this for you and I came up with the following list.

Some of the following criteria are more suitable for MultiP web application.

Popularity and contributor distribution

Selecting a framework is a strategic decision. Popularity guaranties that the framework will be there for a couple of years and not just silently die. Popularity can only be measured indirectly using indicators like the number of web pages speaking about a technology or the traffic on a mailing list.

In addition, it is easier to find developers that have skills in the framework, if a framework is very popular.

You should be aware of the fact that this is not a full guarantee. Popular frameworks like Struts 1 or iBatis died quickly.

The term Contributor Distribution expresses that there is a larger group of contributors and core developers from different companies. If all contributors are from one single company you are totally dependent on what they do and if this company runs out of money or just becomes mad you might be confronted with a change of license or other negative issues.

Ajax support

Interactive web applications are a common practice today and there is no way around. This is why the framework must provide Ajax support. Basically, there are two options: either the tag libraries are already Ajax enabled or alternatively an Ajax library needs to be used.

Rendering technology

A framework may support one or multiple rendering technologies. This can be JSP or another template solution like Freemarker or Velocity. The quality of the tag libraries provided is important as well. Here is just a short list

Validation

In a form a user might input something other than you expected or even worse, he could try to manipulate the request. Depending on the technology you might do the input validation on the client, on the server or on both systems.

A MultiP web application sends the input using a normal HTTP request. The request can easily be manipulated. This is why you always need validation on the server. In addition it would be nice, if the user already gets feedback on missing input without submitting the input to the server. I am speaking about interactive web applications here. With MultiP application this requires Javascript.

We need client validation to give the user a better user experience and server side validation for security reasons. A good framework should be able to provide both with the same set of validation rules.

A SingleP web application rendered by a plugin � these are non Javascript apps � could use client side validation only. It is possible to encrypt the sent data and ensure that the user cannot manipulate the data.

Internationalization

A webframework needs to provide support for internationalized applications. Some but not all applications run in multiple languages. There must be a kind of resource bundle where you define key � value pairs for the texts of your application.

home_title=My homepage
login_title=The login page
pay_title=Become happy and make me rich

But this is not yet a real requirement, it is to basic. A good framework should support modularized resource bundles. In a large application, it will be annoying to have a single resource bundle for 300 different pages. Another requirement is flexibility. I should be able to provide my own mechanism to load the resource bundles. If I prefer to put this into a database then the framework should facilitate doing this.

Finally, during development the resource bundles must be reloadable. It is incredible annoying if you have to redeploy your application just because you forget to add an entry in your resource bundle.

Support for modern patterns used in web applications

We have worked around common problems far too much. I am fed up with writing code over and over again just because web frameworks do not include functionality which I need every time for a proper web application.

Redirect on Post

If a user submits an input form and we render the response page directly, the user will get an annoying 'Do you want to resubmit?' question from this browser when he uses the browser back button.

With Redirect on Post you will no longer see the resubmit question while you are using the browser back button.

Redirect on Post
Redirect on Post describes a pattern where you always redirect to another page after the user has submitted data using a POST request.

If you use the browser back button, than you will just see the content of the page you redirected to. This leads us directly to the next requirement.

Flash scope

We talked about submitting an input form using a POST request. If the validation of the input fails, you do something like

request.setAttribute(�errors�, myErrorMessages);

Depending on the web application you might have an abstraction for this.

If you redirect a request to an other page, the data in the request is lost. You won't be able to show the error messages to the user. And now I present the flash scope, tatatataa. The flash scope solves this problem by storing the content of the flash scope somewhere temporarily and retrieving it again after the redirect.

One approach is to store it into the session and to fetch it from there. There could be considerations, what happens if the user has two windows open. Well, the user must be incredible fast to create a second request which processes faster than the first one and will extract the messages in the flash scope before the second request. Keep in mind that the redirect happens immediately after the POST request has been processed.

A second approach is to pass an ID with the redirect and use the ID to extract the flash content.

http://www.laliluna.de/editProduct?flashid=11

In case you decide not to redirect but to render the screen, the flash context should be removed after it was processed. Otherwise the messages would appear on the next page, you navigate to, as well.

Flash Scope
A flash scope is a context like request or session which stores information to be shown to the user either in the current request or after a redirect in the next request.
The information can include info, error messages or complete objects.

Conversation context

I am not aware of the origin of this context but at least I know that the JBoss Seam framework offers a concept like this.

Why is this useful?

Imagine an application to edit a product. There are three pages you have to step through to edit all values. On the first page you edit the name, on the second the price and on the third the description. One input per page allows us to render the application on your cell phone even if a part of the cell phone screen is broken. ;-)

Where will you store the input from the first page? If you put it in the session and you edit two products at the same time, each dialog will overwrite the values of the other one. The behavior is unpredictable.

If you store the input in the request context, you need to carry it around with every request. You could carry it around in hidden input fields or in a single encrypted field holding all values. This approach is fine for two values but becomes more and more painful if you carry around a lot of input.

This problem is addressed by a conversation context.

When you start to edit a product a conversation context is created. It is identified by an ID and the framework will add the ID to all forms and redirect URLs. Another page starting to edit a product will receive its own conversation context with a different ID. After you have finished editing the product the conversation is removed.

All the conversation contexts can be stored inside a Map in the session context. The key is the ID and the value is the context.

Conversation context
A conversation context is a context like the session or the request context. It is identified by an ID and allows us to create a new context every time a dialog is started. A dialog typically consists of a sequence of pages.

Double submit handling

The framework should be able to deal with double submits. This happens when the user clicks on the submit button multiple times. There are a number of possible reactions. At least the framework should be aware of a double submit and allow to define an error page to be shown. A better approach is to provide a call back method in the action class, mapped bean or whatever the framework uses. This allows us to decide how we want to react depending on other conditions.

The following is an artificial example.

public class ShoppingCartAction {

@DoubleClickHandler
public void doubleClick(Request request){
if (shoppingCartService.cardAllreadyProcessed(request.getValue("cart"))){
infoMessage("You have clicked twice and we ignored it");
redirect("/success");
}else{
errorMessage("You have clicked twice and the order was not processed because of an error.");
redirect("error");
}

}
}



Wizard dialog

The checkout process of a shopping cart is a typical example for a wizard dialog. It is enforced that the user inputs the address first, confirms the Condition of Use, select the payment method, input payment data and finally confirms the complete order. I don't want the user to be able to use the browser back button to restart the process in the middle.

At least in my opinion basic support for this requirement should be available.

Friendly URLs

Friendly URLs express that the user thinks 'Oh, that's a nice website, the URLs look friendly' and that search engines think 'Oh, that's a nice website, I can index it'.

How does a nice URL look like?

http://www.laliluna.de/shop/product/1

How doesn't a nice URL look like?

http://www.laliluna.de/shop.script?task=showProduct&id=1

It is nice if a webframework offers conventions (over configuration) to define default URLs and in addition let you alter them to your needs if required.

Learning curve

How difficult can it be to write 'Hello world' or to craft an input form with validation? It shouldn't be difficult in my opinion. Whether it is difficult to understand the processing behind the scenes, the request cycle or chain of the framework, depends a lot on whether the framework is just a thin layer above the servlet request or if it provides already a lot of functionality to integrate your business layer or persistence layer more easily.

But still if the framework is already doing a lot for you, it should be fully understandable what is happening.

Bad example JavaServer Faces 1.x
Do you understand the JSF request phases? On a first look they look simple but in fact it is a nightmare of things happening and being dependent on each other. It is not at all easily to hook in and change the behavior.
You like JSF and you are not convinced? Then try to write a library which caches a part of your component tree to render the page faster and make sure that it works with GET and PUT requests. You will have fun, believe me.

To summarize, it should be easy to learn the web application and to understand what the application is doing behind the scenes in order to be able to modify the default behavior.

Performance and scalability

A web application should have good performance and scalability.

The Difference between performance and scalability
It is Sunday morning and you want to boil an egg. Without starting a philosophical discussion on boiling of eggs, let's say that it requires 5 minutes.
Good performance is if you only need 3 minutes to boil the egg because you are using your new termo boost cooking appliance.
Scalability is something completely different. For example if you use a SOA based architecture, you have a very scalable technology. A SOA based cooking appliance is able to cook 300 eggs simultaneously but the first one and all the others will arrive after 30 minutes, because the performance totally sucks.
A consultant would tell you 'With SOA you are able to cook an egg in 6 seconds'.

Now we should clearly understand the requirement of performance and scalability. A page should be rendered fast and if the numbers of users grows the application should be able to scale up.

Second try or why the first one sucks?

Do you like the set of criteria? I think it is not bad, it includes business criteria, technical criteria, practical criteria. The only problem with it is, that it totally sucks when we start to apply the criteria to frameworks. I became aware of this deficiency when starting to evaluate the frameworks with the criteria set. Finally, I was convinced at JavaOne 2008 in San Francisco where a presentation followed an approach similar to mine. After they finished presenting the evaluation results, I basically didn't get anything. The evaluation did not bring me forward in the process of deciding which is the the better framework . The presentation were not at all bad, they really worked out good criteria. Have a look, it is available online.

http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-6457&yr=2008&track=nextweb

But the presenters convinced me finally that we need a different approach to select web frameworks. I will give you a number of arguments:

Criteria cannot be compared to each other

Does the fact that JSF frameworks implement a standard and a lot of developers know the framework outweighs the fact that friendly URLs are a problem with JSF? Nobody can tell you. Developing JSF tends to be slowish but can be impressive if you have good IDE support. Is it better than the Stripes framework, which nobody knows but is so easy to learn that you will be up and running 'Hello World' in five minutes?

How to define if a criteria is fulfilled?

We spoke about Ajax support as requirement? Is the Ajax support inside of Tapestry tag libs better than a Stripes framework where you just use the JQuery javascript library to do the interactive stuff? A separate library is more powerful but people need to learn JQuery. On the other hand tag libs with Ajax prevent you from implementing more advanced use cases of interactive dialogs.

I don't think that we able to say, this framework gets a good and the next one a bad evaluation for this criteria.

Scale of criteria

If we try to evaluate the functionality to create interactive dialogs with Ajax, we need to define a scale in order to compare how well a framework fulfills the criteria. In practice, it is very difficult to define that a framework gets 3 out of 5 points for Ajax support. You can validate easily if a scale is going to work. Ask multiple developers to define the functionality for a framework reaching 3 out of 5 points. If you get the same description, you can use the scale.

Are the criteria valid for all frameworks?

The startup time of a SingleP application is perfectly acceptable because once the application is loaded everything can be fast. But I am quite sure that you don't want the web to consist only of SingleP applications. It would drive you crazy while surfing around. Can we really evaluate performance in this context?

Conclusion

We need to find a totally different approach. There is no single set of criteria to evaluate different kind of technologies. I would like to introduce an idea of mine in the next chapter.