Working with REAL Java Objects

Tutorial – Apache Wicket: The Fun Web Framework

JeremyThomerson
apache-wicket

Apache Wicket guru Jeremy Thomerson takes us on a tour of component-oriented Java UI web framework and when best to use it.

There is no lack of variety when choosing your Java technology
stack. In attempts to get away from both the “roll your own
[everything]” thinking that so many companies fall prey to, as well
as the “everything must be a standard” philosophy of others, a wide
range of varying approaches to each layer of the Java architecture
has sprung up over the past years. The UI layer is no stranger to
the struggle of competing technologies. With all of the options
that you are presented with, how are you ever to choose? While no
writer can make that choice for you, what we can do is introduce
you to another option that you may want to consider, with the hopes
that it will intrigue you enough to try it out. In this article,
I’ll introduce you to Apache Wicket.

As you may suspect by the article’s title, Wicket is my
preferred UI framework for most of the applications I write.
Whether you end up sharing that same passion for this great
framework – or whether it fits the type of application you desire
to write – is up to you and your circumstances. But, read on and
you may find another great technology to add to your “go-to”
stack.

What is
Wicket?

Wicket is a component-oriented Java web framework, which focuses
on making it easy to write reusable code. It requires no XML
configuration (aside from a few lines in your standard web.xml
deployment descriptor), making it refreshing to work with. It
encourages a clean separation between your logic and your markup,
appealing to most programmers’ desire for a sense of order. With
Wicket your code is “just Java” and your markup is “just HTML”.
This makes it much easier for “HTML guys” to assist with the
project without fear of messing something up and without having to
learn a complex templating language, parameter names and values, et
cetera.

Wicket appeals to a person who
loves object-oriented programming. Each component on your page is
a
real Java object. It can hold state and perform useful functions
just like any Java object. The nice thing about this is that this
state persists through web requests to abstract the complexities of
the stateless hyper-text transfer protocol from you. Imagine that
you have a page that has an accordion-style panel in the side
navigation bar, as well as a complex data table in the main content
area. A user comes to this page and expands a section of the
accordion. In your code, you may call
setExpandedSection(index),
or you may have
setExpanded(true) on it and
false on the others. However it is that you model your component,
you can store that user-selection as a regular Java member variable
inside your accordion component or one of its children. Now, when
the user clicks a link to restore your complex data table, the
table itself does not need to know about the state of the accordion
component – or any other component on the page. But, the accordion
component, as well as all the others, automatically retain their
state throughout the various other requests that the user
makes.

How does
it work?

To achieve the level of UI complexity described above, many
methodologies require that each component on the page has some
level of knowledge of the other components on the page. In these
other technologies, when I click a link in one component, it needs
to embed the state of the other components into its request.
Perhaps this goes in the URL, or perhaps it is stored in the
session. Maybe each component has a cookie prefix and stores its
state in a cookie. Or, perhaps your programmers get to spend most
of their time configuring interactions between components in a
complex XML file that ties the inputs and outputs of various
components together. Whatever the case, it’s not simple programming
– some of it isn’t even programming at all – and it requires a
constant awareness of the fact that you are writing a stateful
application on a stateless protocol.

Wicket gets around this by
introducing a sort-of state engine to the HTTP interactions of our
web applications. When a user first visits a page, an instance of a
Java class is instantiated. When constructing that class, you
construct its components just like you would instantiate any other
Java class, i.e.
new
MyComponent(“SomeID”)
.

When the state of those
components change, they store that state within themselves as real
variables with real types. After that initial page render, though,
Wicket does not discard the page object that was instantiated. The
entire component hierarchy is stored in the user’s session (as well
as disk in an efficient manner not detailed in this article). So,
when they click a link to take some action on the page, submit a
form, et cetera, all of that state is still contained in those
classes. This is what makes it so simple (and fun!) to work
with.

Now, the first thing that most
people think is “won’t that use a
ton of memory?” The answer
is
no!
Many people have fallen for the trap of assuming that this method
is a memory-waster, but then find that this amounts to premature
optimization. That’s not to say that you can’t kick yourself while
using Wicket – you can certainly do things that will make your
session size explode. We will discuss more about that below in the
section “What Are Models?”. If you’re really concerned about being
able to validate my assertion that Wicket will not use more memory
than other frameworks, you may want to check out this
post
 and another post for
a more elaborate
comparison of Wicket versus several alternative
frameworks
 (both written by
Peter Thomas). If you can just trust me for now, continue
on.

      
 
      

How to get
started

Without further ado, how do you
jump right in and try Wicket out? If you have Maven installed, it
could not be any easier. Simply jump over to
http://wicket.apache.org/start/quickstart.html,
fill in your desired package group and artifact ID’s and run the
provided command. A working quick-start application will be
generated for you. Running
mvn
eclipse:eclipse
(or the equivalent
for your IDE) will set up the project dependencies. If you are
using Eclipse go to the file
menu, select
Import,
then
Import an existing
project
and select the directory
where your quickstart was generated. Find the

Start.java file, open it, and run it. Navigate to http://localhost:8080 and
you will see your “hello world” application in action. By running
the Start class in your IDE’s debug mode (Eclipse:

Debug as | Java
application
) instead of the normal
run mode, you will be able to set breakpoints and debug your
application to see how it works. For more complex quick-start
applications featuring Spring, Guice, JPA, et cetera, see
jWeekend’s excellent LegUp
resources
.

Hello
World

The “hello world” part is
already done for you by the archetype. So, let’s create a simple
example of a link that increments a counter on the page. To get
started (assuming you have the simple quickstart above running),
find the
HomePage.java
and HomePage.html files and open
them in your editor. Note that unless otherwise mentioned, all
examples in this article will be based on the latest stable
release, 1.4.18 (at the time of writing)

Let’s look at the HTML first.
The first thing that you probably notice is that it is just regular
HTML. This is by design. Markup should not contain logic – that’s
Wicket’s philosophy. To tie a piece of markup to corresponding Java
code that controls it you simply add the
wicket:id attribute to it.
We had two things in this markup that were dynamic. The most
obvious was the link. The second is a span that renders the value
of the counter on each page render. We use a span tag simply
because we need a markup placeholder for the value to be inserted,
and a span tag will not disrupt the structure of our other
markup.

HomePage.html

 

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
    <head>  
        <title>Wicket Quickstart Archetype Homepage</title>
    </head>
    <body>
        <strong>Wicket Quickstart Archetype Homepage</strong>
        <br/><br/>
        Click <a href="#" wicket:id="increment">this link</a> to increment 
        the following counter:<br />
        Counter: <span wicket:id="counter">123</span>
    </body>
</html>

 

Now, let’s look at the
associated Java code. The first thing you should note is the name
and placement of the files. By default, for any Wicket component
(pages, as we are using here, are also components, so the same rule
applies), Wicket will look in the same package directory on the
classpath for a file with the same name, with the extension .html
(if you are rendering XML, this would still apply, but with
a
.xml extension). This behavior can be re-configured, but for
this article we will not get into that. There are online resources
that can assist you with that if needed.

When you examine the actual
code, you will see several parts. The first thing you see is
the
counterModel. You notice
that it implements
IModel. Models are extremely
important in Wicket. They’re also generally one of the least
understood concepts when programmers first adopt Wicket. We’ll
discuss them more later. For now, suffice to say that they are a
wrapper for retrieving or setting a piece of data, and this

AbstractReadOnlyModel, as its name implies, is simply a wrapper for retrieving
data. We implement the
getObject method to retrieve
the current value of counter on every invocation. This model is
then passed to a
Component. In this case the
component is a Label. A label simply takes whatever tag it is
associated to in the markup and replaces the body of that tag with
the value retrieved from the model it is given. In this case, our
span tag will replace “123” (its static body in the markup) with
the value of our counter, which on the first page render will be
zero.

The next thing you see is the
link. It gives you just a glimpse of the power of Wicket. We’re
using an anonymous inner class here to implement the link. If you
had multiple places in your application that needed to increment an
integer, you could replace this with a concrete class simply by
extracting the anonymous inner class into a real top-level
class.

Now, look at how simple it is to
implement an action of any sort on a link. You simply override
the
onClick method and put your business logic in there. Obviously
incrementing a counter is a simple example, but you could just as
easily call a service- layer method that deleted or edited
something in your domain, sent an email, or made a web service
call. Wicket does the hard part for you. You implement the logic
and you don’t have to worry about how to get a URL that will
indicate to run that small bit of logic. You don’t have to worry
about where to store the current state of the counter. All you have
to do is write your code that performs the work that your
application is designed to do. That’s why I love Wicket!

 HomePage.java

 

public class HomePage extends WebPage {
    private static final long serialVersionUID = 1L;

    private int counter = 0;
    
    public HomePage() {
        IModel<Integer> counterModel = new AbstractReadOnlyModel<Integer>() {
            private static final long serialVersionUID = 1L;

            @Override
            public Integer getObject() {
                return counter;
            }
        };

        Label label = new Label("counter", counterModel);
        add(label);
        
        Link<Void> link = new Link<Void>("increment") {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClick() {
                counter++;
            }
        };
        add(link);
    }
}

 

        
      What
about AJAX?

Okay, so it’s easy to make a
link. So what, right? Now watch how easy it is to make that link an
AJAX link that fully supports non-AJAX requests. First, we make our
label instance final so that we can access it within the anonymous
inner class and we call
setOutputMarkupId(true) so
that its unique ID is rendered in the span tag and it can be found
in the DOM on the client-side. We change our
Link class to
AjaxFallbackLink and change the onClick method signature to
match the superclass. The
AjaxRequestTarget that is
passed in can be thought of as a queue of things to send back in
XML to the client side for processing. By adding the label to that
queue, it will be re-rendered, streamed across the wire in XML and
replaced in the DOM on the client-side. When it is re-rendered, it
will use its model (remember
counterModel?) to get the
up-to-date value to render. All without us writing a line of code
that does any transformations or DOM manipulation!

Why do we check if the
AjaxRequestTarget is null? Because this link will automatically work for you
on browsers that do not have JavaScript enabled. In this event, the
page would simply re-render just like it did with a regular link.
Yes, you heard me – it degrades gracefully without any additional
work! Almost too good to be true, right? You’ll find that Wicket
works this way for you by default most of the time. Form
submissions and even file uploads can be done in either regular
HTTP or AJAX with very little, if any, extra work. And in the 1.5
version, a very handy event mechanism is added to make the work of
adding components to the
AjaxRequestTarget even
easier. 

HomePage.java (note: only the constructor is
shown)

public HomePage() {
    IModel<Integer> counterModel = new AbstractReadOnlyModel<Integer>() { … }
    // above code folded for brevity

    final Label label = new Label("counter", counterModel);
    add(label.setOutputMarkupId(true));
    
    AjaxFallbackLink<Void> link = new AjaxFallbackLink<Void>("increment") {
        private static final long serialVersionUID = 1L;

        @Override
        public void onClick(AjaxRequestTarget target) {
            counter++;
            if (target != null)
                target.addComponent(label);
        }
    };
    add(link);
}

Working
With User Input

In many web applications, a lot
of the work to be done in building the app goes into the forms that
accept user input. In Wicket, forms are regular objects just like
all other components. To see an example, let’s look at a simple
form that accepts a user’s name, email, and date of
birth

 

Looking at the HTML, you see that there is nothing special about
it. Your designers can give you an HTML form and you can add
wicket:id attributes to the input fields and the form itself. The
div with the wicket:id “feedback” is a placeholder for a built-in
Wicket component that shows the user all feedback messages that
were generated by the form. In the picture above, the user has just
submitted the form with bad data which caused validation messages
to appear in our feedback panel component. These can easily be
customized to have a feedback panel near each form field that only
shows the messages for that particular field – a common requirement
in many applications.

Example of a Single Form

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
    <head>  
        <title>Quickstart Homepage</title>
    </head>
    <body>
        Add / Edit Person:
        <div wicket:id="feedback"></div>
        <form wicket:id="form">
            First Name: <input type="text" wicket:id="firstName" /><br />
            Email Address: <input type="text" wicket:id="email" /><br />
            Date of Birth: <input type="text" wicket:id="dob" /><br />
            <input type="submit" value="Save" />
        </form>
    </body>
</html>

Now looking at the Java code,
you see that we created two constructors. This is so the form can
be used as both an “add person” and an “edit existing person” form.
By default, the no-argument constructor is called which makes this
an “add person” form because it is using a model that holds a new
person. But, a link could easily be written that shows the user an
“edit person” page simply by passing a model to the page with an
existing person. (Note that we don’t cover that example in this
article, but if you were doing this, you would likely want to use
a
LoadableDetachableModel,
which is discussed more in the section on models.)

Next you see that we instantiate
our
Form object. We implement the onSubmit method and make it
contain our business logic – in this case a simple call to a
service-layer class. Moving along, you see where we create each
field and configure it with our UI rules – which fields are
required, and what is required of them (for instance, a valid email
address format). What you don’t see is refreshing – no calls
to
HttpRequest
to get strings out, no conversion of strings to
dates, no manual retrieval of data from our form post and no manual
setting of data on our backing Person object. In long forms, this
saves hundreds of lines of copy-and-paste and highly error-prone
code. This is because we are dealing with
real Java objects – not a
bunch of strings that have to be manually manipulated. See the form
processing image in the “top ten” list and the link to the full top
ten list below for more information.

Note that we are using a
service-layer object (
IPersonService) to do our
persistence. This is a Spring-managed bean, and it is extremely
simple to use because of Wicket’s built-in Spring (or Guice, if you
prefer) integration.

Form object 

public class HomePage extends WebPage {
    
    @SpringBean
    IPersonService personService;
    
    public HomePage() {
        this(new Model<Person>(new Person()));
    }

    public HomePage(IModel<Person> model) {
        Form<Person> form = new Form<Person>("form", model) {
            protected void onSubmit() {
                Person person = this.getModelObject();
                System.out.println("Saving: " + person);
                personService.savePerson(person);
            }
        };
        
        TextField<String> firstName = new TextField<String>("firstName", new PropertyModel<String>(model, "firstName"));
        firstName.setRequired(true);
        form.add(firstName);
        
        TextField<Date> dob = new TextField<Date>("dob", new PropertyModel<Date>(model, "birthDate"));
        dob.setRequired(true);
        form.add(dob);
        
        TextField<String> email = new TextField<String>("email", new PropertyModel<String>(model, "emailAddress"));
        email.setRequired(true);
        email.add(EmailAddressValidator.getInstance());
        form.add(email);
        
        add(form);
        add(new FeedbackPanel("feedback"));
    }
}

What are
Models?

In the code examples, you’ve seen several mentions of models,
earlier described as “a wrapper for retrieving or setting a piece
of data”. So, just what is a model, and why is it so important? As
mentioned earlier, Wicket stores your entire component hierarchy
(the page and all the components you added to it, as well as
components added to those components and so on) in memory, and then
to disk so that you have a stateful way of working with Java
objects over the stateless HTTP. But these components that display
this data do not necessarily need to store the data itself between
requests. They only need to store their state – perhaps a flag
indicating if they are visible or invisible, enabled or disabled,
expanded or collapsed. It is very likely that the actual data they
are displaying is already persisted elsewhere – likely in the
database, meaning that we don’t really need to save it to the
users’ HTTP sessions. This is one reason models exist – to cut down
on the amount of memory needed to persist our component
hierarchy.

A second, and just as important
reason, is to abstract the retrieval and storage of data from the
component itself. Think of our simple TextField component in our
form example above. It does not need to know if the string that it
is editing is coming from the session, from a web service, or from
a field on a POJO. It simply needs to be able to get a string from
somewhere and set an edited string somewhere. The

IModel interface has two methods for this – getObject and
setObject
that allow it to do just that. Before you start using Wicket, you
should review my
resource page
on them too

      

Top 10 Things Every Wicket Programmer Should Know

 This is a condensed version of my list of the top ten
things that every Wicket programmer should know. For the complete
version, see

http://wickettraining.com/resources/ten-things-every-wicket-programmer-should-know.html

  1. Models – Really make sure
    that you understand models before writing any large application in
    Wicket.
  2. Pull, don’t push – In
    general, your components should be able to
    pull their state rather than
    having some other component
    push the state on it. The
    example below demonstrates what this means and why it’s important.
    The key is that
    the constructor only runs
    once
    , but many things on the page might
    change state after the constructor is run. If you

    push your
    state into components in your constructor, they are out-of-date as
    soon as another component changes state. The only alternative is
    that every component must know about all other components that
    share state – and that’s not “the Wicket way”. Your components
    should be independent and reusable.
  3. Wicket is a UI framework
    Don’t write middle tier or persistence code in Wicket.
  4. Keep markup and code clean and compact
    – Become familiar with and use the various
    aspects of Wicket that allow for reusability – panels, markup
    inheritance, and fragments as examples.
  5. Match your hierarchies – It
    won’t take you long at all to learn this rule, but the hierarchy of
    components in your markup (tags with a wicket:id attribute) must
    match the hierarchy in your Java code.
  6. Form processing lifecycle
    When dealing with forms, it is important to understand the order of
    operations of the form post processing. If any step in the process
    fails the
    onError
    method of your form and submitting button will
    be called
    rather than
    the onSubmit method
    (picture below
    )
  7. Java nuances – There are
    two Java nuances that catch many Wicket newcomers off-guard –
    serialization and the presence of anonymous inner classes.

    Become more familiar with both.
  8. Unit testing – Testing your
    Wicket code is made relatively easy by using
    WicketTester. Try it
    out.
  9. i18n – Internationalization
    is made very easy with Wicket. Become familiar with things like
    wicket:message and file naming standards for Wicket’s built-in i18n
    support.
  10. Where to find help – Wicket
    code is well documented, so reading JavaDocs is a good start.
    Wicket examples can be viewed online at GitHub
    .
    Additionally, Wicket has one of busiest and most helpful mailing
    lists of any open source project. For more information on the
    Wicket mailing lists, see
    http://wicket.apache.org/help/email.html.

Conclusions

I chose Apache Wicket because other frameworks sucked the fun
out of web programming (okay, this is subjective, but I can say
that I didn’t personally enjoy them). Most of my time seemed to be
spent dealing with pushing state around or writing configuration in
XML. Every little change required changes in multiple files – many
times in XML, Java, and specialized markup files. It was hard to
make cohesive reusable components. A few days with Wicket made me
see how drastically different it was. I was writing real Java
object-oriented code, and easily creating reusable components. I
hope that you will give it a few days for your own project or
experiment so that you, too can discover how much fun web
programming can be.

For more information on Wicket,
see
http://wickettraining.com/resources

Jeremy Thomerson is a technology enthusiast who loves
exploring, learning, and creating new technologies. He has helped
numerous companies upgrade their architectures to multi-tier
architectures primarily based on the leading Java open source
technologies, including Wicket, Spring, Lucene, Hibernate and more.
For the past several years, he has owned and operated the leading
U.S. company providing Wicket training and consulting
services.

This article originally appeared in Java Tech Journal – Java Web
Frameworks. You’ll find more of that issue here for
download
.

Author
JeremyThomerson
Jeremy Thomerson is a technology enthusiast who loves exploring, learning, and creating new technologies. He has helped numerous companies upgrade their architectures to multi-tier architectures primarily based on the leading Java open source technologies, including Wicket, Spring, Lucene, Hibernate and more. For the past several years, he has owned and operated the leading U.S. company, WicketTraining.com providing Wicket training and consulting services.
Comments
comments powered by Disqus