A year or so back I attempted to learn JSF and even bought one of the recommended books. But after reading through the first hundred or so pages, I came to the conclusion that it was too complicated and un-intuitive. The code samples looked ugly to me in a way that was difficult to explain. The fact that there was a different expression language (with a ‘#’ instead of ‘$’) to get used to when I was just getting comfortable with JSP EL did not help either.
So I gave up trying to learn JSF and decided to concentrate on Spring MVC at that time.
Fast forward to today and the main trigger for my current experiments with JSF is because after my recent blog post on migrating from Spring MVC / WebFlow to Wicket, I am increasingly being asked whether I ever tried JSF.
So I have attempted to write a very simple application (based on MyFaces) and I will try to compare it side by side with the exact same functionality implemented in Wicket. I just started with JSF a couple of days back so feel free to comment and let me know if I missed something fundamental and I will update things either in this post or the next.
This is supposed to be a “discussion forum” application and there is only one domain object called “Forum” with two String fields “name” and “description”. Maybe in the future I will include “Topic” and “Message” objects but for now I’m trying to keep things as simple as possible.
There are only two screens. The home page is a list of Forum(s) in the system. There is a link to create a new Forum. This brings up the other screen which is a form with two text fields and a submit button. After a successful submission, you are taken back to the home page and the newly created Forum appears in the list.
NetBeans 5.5 is being used. I deploy to a Jetty instance that I set up manually because I want to also compare the Jetty “footprint” required for Wicket vs MyFaces. With some digging I’ve tried to arrive at the bare minimum “quickstart” config required, for example the web.xml file cannot be possibly smaller. I’m using Maven2 directory and naming conventions. Defaults are used as far as possible. In the side by side comparison images below JSF is on the left and Wicket is on the right.
So here goes:
- Wicket does not require any extra XML config like you have faces-config.xml for JSF
- Wicket does not require JSPs
- By default, Wicket expects the markup (*.html files) to be side by side with the *.java files corresponding to components – e.g. Page(s). Some people find this a bit odd but this keeps things simple and there are some very good reasons for this. You can change this convention if you really want to.
- The MyFaces application requires an “index.jsp” welcome-file to redirect to the virtual home page URL
Since Wicket does not require JSP support – the Jetty footprint is much smaller – the contents of the Jetty “lib” folder come down from 6.16 MB to 692 KB
Even without using Tomahawk etc., MyFaces requires far more dependencies than Wicket i.e. 10 vs 4 JAR files
Wicket does not require any kind of XML configuration at all and the “faces-config.xml” file does not have any equivalent. Navigation logic is performed in pure Java code which is much more flexible and type-safe and you don’t need to synchronize multiple files.
A servlet filter handles all the framework stuff in Wicket. This has some advantages like you can map the root of your context path “/” to the home page. Anything not meant for the Wicket filter like images, css reources etc. will be ignored by the filter.
You need to tell Wicket where your “Application” class is located. This Application class is used primarily to point to the designated home page.
The Wicket Application Class
In a real life application, this is where you would manage references to the service-layer, configure security and various other things. Here we are just configuring the home page.
The “List Forums” Screen
- The wicket markup is pure HTML but the MyFaces JSP is a mixture of JSP, HTML, JSF tags and JSF EL
- In the case of Wicket you can see that the complexity clearly moves out of the markup into the Java code. In the JSF version, the only thing the backing class is doing is setting up the model / list
- You don’t need a specialized IDE to edit the Wicket version – HTML editing and Java editing support is sufficient. In the case of JSF you have to rely on IDE support when the UI gets complex
- If you make a spelling mistake in the JSF EL expressions – you won’t know until run time – but the Java code that renders dynamic data in the Wicket version does not have that problem, you benefit from your IDE syntax coloring, refactoring suppport etc.
- The JSF version is using a “dataTable” control. For Wicket we are using a ListView repeater control and creating a table manually. Even then, this is very simple code and you have much more control over the markup. The JSF dataTable documentation is not for the faint of heart and runs into a few pages. That is a lot of complexity you don’t need most of the time. BTW Wicket does provide a range of grid controls in the Wicket extensions project
- Instead of navigation rules defined in faces-config.xml and the need to synchronize this with the action /event names you use in your JSP or backing class – in Wicket you can easily navigate from page to page by using the right “Link” components or setResponsePage()
- Instead of using “id” which has a lot of significance in terms of (X)HTML – Wicket uses a namespace so “wicket:id” is the attribute you use to link your Java code and markup. Relying on the “id” attribute can lead to all kinds of unpleasant name collisions in JSF.
The “Create New Forum” Form
In addition to the points in the previous section:
- In JSF you declare and configure components in the markup and you have to use the right tags (e.g. h:form, h:inputText, h:commandButton) and the right attributes (e.g. to mark an input field as “required”). JSF is supposed to be a component oriented framework but I wouldn’t call them Java components and definitely not Object Oriented.
- In Wicket you use normal HTML tags in the markup and in the Java code, you instantiate and attach the core components (e.g. TextField) or extend them as required (e.g. Form). All the behavior, and things like setting a field as “required” happen in pure Java code.
- In this case for Wicket the value of the “wicket:id” attribute on the input text fields also serves as OGNL notation for HTML form –> POJO binding – which reduces the amount of configuration.
- Rather than rely on a h:panelGrid to layout the form fields it is easier and more intuitive to use plain old HTML tables for this purpose.
- The screenshot below demonstrates how the “ForumFormPage.html” file looks like when opened in a browser. Being valid HTML, Wicket markup files can be previewed and edited as such. Wicket provides for true separation of concerns and HTML screen design and layout can *really* be done by a team separate from the Java development team
You can click on the links below to see the output. If your browser renders the HTML instead of displaying the raw text, just do “view source”.
For Wicket, the generated HTML is clean like you would expect. And note that the Wicket specific attributes like “wicket:id” will be stripped in PRODUCTION mode.
Update [2007-06-10]: Simplified the wicket code for the “Create New Forum” form after it dawned on me that the existing POJO is more than sufficient for form binding. The older version can be found here: forum-form-screen2.png
The Java code for the Wicket form page can be made even more tighter using an anonymous inner class for the form. This is a nice example of how Wicket gets you to exercise the Java OO parts of your brain, and it is worth comparing this with the “ForumFormPage.java” above.
Update: I uploaded the Java and HTML source for the 2 Wicket pages. Since WordPress has restrictions on uploads (no *.zip allowed for e.g.), you have to rename the files correctly if you download them – Forum List Page: HTML / Java | Forum Form Page: HTML / Java