Wednesday, February 18, 2009

Introduction to "Wicket" Web Framework

Wicket, is an open source, lightweight, component-based Java web framework
that brings the Java Swing event-based programming model to web development

Wicket allows you to easily customize this default behavior though. All user pages typically extend Wicket’s WebPage—a subclass of Wicket’s Page class. There needs to be a one-to-one correspondence between the HTML elements with a wicket:id attribute and the Page components

In Wicket,a model (an object implementing the IModel interface) acts as the source of data for a component..

Wicket could also be classified as an event-driven framework. Wicket HTML components
register themselves as listeners (defined through several Wicket listener interfaces) for requests originating from the client browser. For example, Wicket’s Form component registers itself as an IFormSubmitListener, while a DropDownChoice implements the IOnChangeListener interface. When a client activity results in some kind of request on a component, Wicket calls the corresponding listener method. For example, on an HTML page submit, a Form component’s onSubmit() method gets called, while a change in a drop-down selection results in a call to DropDownChoice.onSelectionChanged

With proper mark-up/logic separation, a POJO data model, and a refreshing lack of XML, Wicket makes developing web-apps in Java simple and enjoyable again. Swap the boilerplate, complex debugging and brittle code for powerful, reusable components written with plain Java and HTML.

The component’s id value must match the wicket:id attribute of the
template’s corresponding HTML component

During the page render phase, Wicket does the following:
1. It kicks off the page rendering process by calling the Page.render() method.
2. The Page locates the corresponding markup template and begins iterating over the
HTML tags, converting them into an internal Java representation in the process.
3. If a tag without wicket:id is found, it is rendered as is.
4. If a tag with wicket:id is found, the corresponding Wicket component in the Page is located, and the rendering is delegated to the component.
5. The Page instance is then stored in an internal store called PageMap. Wicket maintains one PageMap per user session.

In Wicket, the component hierarchy is specified explicitly through Java code—which allows you to modularize code and reuse components via all the standard abstraction features of a modern object-oriented language. This is quite different from other frameworks like Tapestry, wherein the page components are typically specified in an XML page specification file listing the components used in the page

WicketServlet expects to be supplied with an IWebApplicationFactory implementation in
order to delegate the responsibility of creating the WebApplication class. A factory implementation could be specified as a servlet initialization parameter in web.xml against the key application➥FactoryClassName. In the absence of such an entry, WicketServlet uses ContextParamWeb➥ApplicationFactory by default. As the name suggests, this class looks up a servlet context parameter to determine the WebApplication class name. The expected web.xml param-name in this case is
applicationClassName. ContextParamWebApplicationFactory works perfectly for majority of the cases Register the CompoundPropertyModel instance with the parent component,
* Form in this case, for the children to inherit from. So all the * remaining components will then use the UserProfile instance * as its model, using OGNL like 'setters' and 'getters'

Wicket’s CompoundPropertyModel allows you to use each component’s ID as a property-path expression to the parent component’s model

Wicket looks for the presence of a system property called wicket.configuration first. If it doesn’t find one, it looks for the value corresponding to a servlet initialization parameter named configuration. In the absence of the preceding settings, it looks for an identical servlet context parameter setting. If none of the
preceding listed lookups succeed, Wicket configures the application in development mode by default. Note that the value for configuration has to be either development or deployment identified by fields wicket.Application.DEVELOPMENT and wicket.Application.DEPLOYMENT, respectively

You must be curious about the parameter bookmarkablePage in the URL. Actually, there is nothing special that makes the page bookmarkable. Any page is considered bookmarkable if it has a public default constructor and/ or a public constructor with a PageParameters argument. A bookmarkable page URL can be cached by the browser and can be used to access the page at a later point in time, while a nonbookmarkable
page cannot be accessed this way. A non-bookmarkable page URL makes sense only in the
context it was generated. If the page wants to be bookmarkable and accept parameters off the URL, it needs to implement the Page(PageParameters params) constructor

After the page is rendered, it is put into a PageMap. The PageMap instance lives in session and keeps the last n pages ( this number is configurable through Wicket’s ApplicationSettings object). When a form is submitted, the page is brought back from PageMap and the form handler is executed on it. The PageMap uses a Least Recently Used (LRU) algorithm by default to evict pages—to reduce space taken up in session.
You can configure Wicket with your own implementation of the eviction strategy. Wicket specifies the strategy through the interface wicket.session.pagemap.IPageMapEvictionStrategy. You can configure
your implementation by invoking getSessionSettings().setPageMapEvictionStrategy
(yourPageMapEvicationStrategyInstance) in the WebApplication.init() method

Component.setResponsePage method can be used to direct the user to a different page after page submit feedback component using Wicket’s built-in ListView

Wicket has a FeedbackPanel component that can display all types of messages associated with components nested within a page

Note that Wicket does call validate() on the subsequent components,
even if a component featured ahead in the page hierarchy has failed validation, accumulating the error messages on the way.

Validation in Wicket is specified through the IValidator interface. Since you can attach any number of IValidator interface implementations to a Wicket component through the component’s overloaded add() method, Wicket developers have made sure that they can be chained as well Validators are thread-safe. It is OK to link the same validator instance with multiple components

It acts as a translation layer between HTTP request parameters
and your model class, and the way it does this is through converters
Wicket accesses the converters through a factory class and makes it centrally available through Wicket’s ApplicationSettings class

All converters are supposed to implement the IConverter interface. It has a single
method: public Object convert(Object value, Class c)
All components allow you to specify the custom converter through the
getConverter() method

FeedbackMessages acts as a container for messages logged at any level, namely debug, info, error, warn. You can access messages specified at a particular log level in the form of a list (java.util.List) by supplying a filter of the type IFeedbackMessageFilter to FeedbackMessages

Print this post