4. Wicket says “Hello world!”
Wicket allows us to design our web pages in terms of components and containers, just like AWT does with desktop windows. Both frameworks share the same component-based architecture: in AWT we have a Windows instance which represents the physical windows containing GUI components (like text fields, radio buttons, drawing areas, etc…), in Wicket we have a WebPage instance which represents the physical web page containing HTML components (pictures, buttons, forms, etc… ) .
@startuml
package java.awt {
class Component
class Window extends Component
Window "*" *-- "1" Component
}
package org.apache.wicket {
class org.apache.wicket.Component
class WebPage extends org.apache.wicket.Component
WebPage "*" *-- "1" org.apache.wicket.Component
}
@enduml
In both frameworks we find a base class for GUI components called Component. Wicket pages can be composed (and usually are) by many components, just like AWT windows are composed by Swing/AWT components. Both frameworks promote the reuse of presentation code and GUI elements building custom components. Even if Wicket already comes with a rich set of ready-to-use components, building custom components is a common practice when working with this framework. We’ll learn more about custom components in the next chapters.
4.1. Wicket distribution and modules
Wicket is available as a binary package on the main site http://wicket.apache.org . Inside this archive we can find the distribution jars of the framework. Each jar corresponds to a sub-module of the framework. The following table reports these modules along with a short description of their purpose and with the related dependencies:
Module’s name | Description | Dependencies |
wicket-core | Contains the main classes of the framework, like class Component and Application. | wicket-request, wicket-util |
wicket-request | This module contains the classes involved into web request processing. | wicket-util |
wicket-util | Contains general-purpose utility classes for functional areas such as I/O, lang, string manipulation, security, etc… | None |
wicket-bean-validation | Provides support for JSR 303 standard validation. | wicket-core |
wicket-devutils | Contains utility classes and components to help developers with tasks such as debugging, class inspection and so on. | wicket-core, wicket-extensions |
wicket-extensions | Contains a vast set of built-in components to build a rich UI for our web application (Ajax support is part of this module). | wicket-core |
wicket-auth-roles | Provides support for role-based authorization. | wicket-core |
wicket-ioc | This module provides common classes to support Inversion Of Control. It’s used by both Spring and Guice integration module. | wicket-core |
wicket-guice | This module provides integration with the dependency injection framework developed by Google. | wicket-core, wicket-ioc |
wicket-spring | This module provides integration with Spring framework. | wicket-core, wicket-ioc |
wicket-velocity | This module provides panels and utility class to integrate Wicket with Velocity template engine. | wicket-core |
wicket-jmx | This module provides panels and utility class to integrate Wicket with Java Management Extensions. | wicket-core |
wicket-objectsizeof-agent | Provides integration with Java agent libraries and instrumentation tools. | wicket-core |
Please note that the core module depends on the utility and request modules, hence it cannot be used without them.
4.2. Configuration of Wicket applications
In this chapter we will see a classic Hello World! example implemented using a Wicket page with a built-in component called Label (the code is from the HelloWorldExample project). Since this is the first example of the guide, before looking at Java code we will go through the common artifacts needed to build a Wicket application from scratch.
All the example projects presented in this document have been generated using Maven and the utility page at http://wicket.apache.org/start/quickstart.html . Appendix A contains the instructions needed to use these projects and build a quickstart application using Apache Maven. All the artifacts used in the next example (files web.xml, HomePage.class and HomePage.html) are automatically generated by Maven. |
4.2.1. Wicket application structure
A Wicket application is a standard Java EE web application, hence it is deployed through a web.xml file placed inside folder WEB-INF:
Illustration: The standard directory structure of a Wicket application
The content of web.xml declares a servlet filter (class org.apache.wicket.Protocol.http.WicketFilter) which dispatches web requests to our Wicket application:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>Wicket Test</display-name>
<filter>
<filter-name>TestApplication</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>org.wicketTutorial.WicketApplication</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>TestApplication</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Since this is a standard servlet filter we must map it to a specific set of URLs through the
If we are using Servlet 3 or a later version, we can of course use a class in place of web.xml to configure our application. The following example uses annotation WebFilter.
@WebFilter(value = "/*", initParams = {
@WebInitParam(name = "applicationClassName", value = "com.mycompany.WicketApplication"),
@WebInitParam(name="filterMappingUrlPattern", value="/*") })
public class ProjectFilter extends WicketFilter {
}
Wicket can be started in two modes named respectively DEVELOPMENT and DEPLOYMENT. The first mode activates some extra features which help application development, like resources monitoring and reloading, full stack trace rendering of exceptions, an AJAX debugger window, etc… The DEPLOYMENT mode turns off all these features optimizing performances and resource consumption. In our example projects we will use the default mode which is DEVELOPMENT. Chapter 24.1 contains the chapter “Switching Wicket to DEPLOYMENT mode“ where we can find further details about these two modes as well as the possible ways we have to set the desired one. In any case, DO NOT deploy your applications in a production environment without switching to DEPLOYMENT mode! |
4.2.2. The application class
If we look back at web.xml we can see that we have provided the Wicket filter with a parameter called applicationClassName. This value must be the fully qualified class name of a subclass of org.apache.wicket.Application. This subclass represents our web application built upon Wicket and it’s responsible for configuring it when the server is starting up. Most of the times our custom application class won’t inherit directly from class Application, but rather from class org.apache.wicket.protocol.http.WebApplication which provides a closer integration with servlet infrastructure. Class Application comes with a set of configuration methods that we can override to customize our application’s settings. One of these methods is getHomePage() that must be overridden as it is declared abstract:
public abstract Class<? extends Page> getHomePage()
As you may guess from its name, this method specifies which page to use as a homepage for our application. Another important method is init():
protected void init()
This method is called when our application is loaded by the web server (Tomcat, Jetty, etc…) and is the ideal place to put our configuration code. The Application class exposes its settings grouping them into interfaces (you can find them in package org.apache.wicket.settings). We can access these interfaces through getter methods, which will be gradually introduced in the next chapters when covering related settings.
The current application’s instance can be retrieved at any time by calling static method Application.get() in our code. We will give more details about this method in chapter 9.3. The content of the application class from the HelloWorldExample project is the following:
public class WicketApplication extends WebApplication
{
@Override
public Class<? extends WebPage> getHomePage()
{
return HomePage.class;
}
@Override
public void init()
{
super.init();
// add your configuration here
}
}
Since this is a very basic example of a Wicket application, we don’t need to specify anything inside the init method. The home page of the application is the HomePage class. In the next paragraph we will see how this page is implemented and what conventions we have to follow to create a page in Wicket.
Declaring a WicketFilter inside web.xml descriptor is not the only way we have to kick-start our application. If we prefer to use a servlet instead of a filter, we can use class org.apache.wicket.protocol.http.WicketServlet. See the JavaDoc for further details. |
4.3. The HomePage class
To complete our first Wicket application we must explore the home page class that is returned by the Application‘s method getHomePage() seen above. In Wicket a web page is a subclass of org.apache.wicket.WebPage. This subclass must have a corresponding HTML file which will be used by the framework as template to generate its HTML markup. This file is a regular plain HTML file (its extension must be html).
By default this HTML file must have the same name of the related page class and must be in the same package:
Illustration: Page class and its related HTML file
If you don’t like to put class and html side by side (let’s say you want all your HTML files in a separated folder) you can use Wicket settings to specify where HTML files can be found. We will cover this topic later in chapter 16.14.
The Java code for the HomePage class is the following:
package org.wicketTutorial;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.WebPage;
public class HomePage extends WebPage {
public HomePage() {
add(new Label("helloMessage", "Hello WicketWorld!"));
}
}
Apart from subclassing WebPage, HomePage defines a constructor that adds a Label component to itself. Method add(Component component) is inherited from ancestor class org.apache.wicket.MarkupContainer and is used to add children components to a web page. We’ll see more about MarkupContainer later in chapter 5.2. Class org.apache.wicket.markup.html.basic.Label is the simplest component shipped with Wicket. It just inserts a string (the second argument of its constructor) inside the corresponding HTML tag. Just like any other Wicket component, Label needs a textual id (‘helloMessage’ in our example) to be instantiated. At runtime Wicket will use this value to find the HTML tag we want to bind to the component. This tag must have a special attribute called wicket:id and its value must be identical to the component id (comparison is case-sensitive!).
Here is the HTML markup for HomePage (file HomePage.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Apache Wicket HelloWorld</title>
</head>
<body>
<div wicket:id="helloMessage">
[Label's message goes here]
</div>
</body>
</html>
We can see that the wicket:id attribute is set according to the value of the component id. If we run this example we will see the text Hello WicketWorld! Inside a
Label replaces the original content of its tag (in our example [Label’s message goes here]) with the string passed as value (Hello WicketWorld! in our example) |
If we specify a wicket:id attribute for a tag without adding the corresponding component in our Java code, Wicket will throw a ComponentNotFound Exception. On the contrary if we add a component in our Java code without specifying a corresponding wicket:id attribute in our markup, Wicket will throw a WicketRuntimeException. |
4.4. Wicket Links
The basic form of interaction offered by web applications is to navigate through pages using links. In HTML a link is basically a pointer to another resource that most of the time is another page. Wicket implements links with component org.apache.wicket.markup.html.link.Link, but due to the component-oriented nature of the framework, this component is quite different from classic HTML links. Following the analogy with GUI frameworks, we can consider Wicket link as a “click” event handler: its purpose is to perform some actions (on server side!) when the user clicks on it.
That said, you shouldn’t be surprised to find an abstract method called onClick() inside the Link class. In the following example we have a page with a Link containing an empty implementation of onClick:
public class HomePage extends WebPage {
public HomePage(){
add(new Link<Void>("id"){
@Override
public void onClick() {
//link code goes here
}
});
}
}
By default after onClick has been executed, Wicket will send back to the current page to the client web browser. If we want to navigate to another page we must use method setResponsePage of class Component:
public class HomePage extends WebPage {
public HomePage(){
add(new Link<Void>("id"){
@Override
public void onClick() {
//we redirect browser to another page.
setResponsePage(AnotherPage.class);
}
});
}
}
In the example above we used a version of setResponsePage which takes as input the class of the target page. In this way a new instance of AnotherPage will be created each time we click on the link. The other version of setResponsePage takes in input a page instance instead of a page class:
@Override
public void onClick() {
//we redirect browser to another page.
AnotherPage anotherPage = new AnotherPage();
setResponsePage(anotherPage);
}
The difference between using the first version of setResponsePage rather than the second one will be illustrated in chapter 8, when we will introduce the topic of stateful and stateless pages. For now, we can consider them as equivalent.
Since Wicket 8 is built on Java 8, we can choose to leverage lambda expressions to specify handler method:
//create a standard link component
add(ComponentFactory.link("id", (newlink) -> {/*do stuff*/});
Factory class ComponentFactory is provided by the WicketStuff project. You can find more information on this project, as well as the instructions to use its modules, in Appendix B.
Wicket comes with a rich set of link components suited for every need (links to static URL, Ajax-enhanced links, links to a file to download, links to external pages and so on). We will see them in chapter 10.
We can specify the content of a link (i.e. the text inside it) with its method setBody. This method takes in input a generic Wicket model, which will be the topic of chapter 11. |
4.5. Summary
In this chapter we have seen the basic elements that compose a Wicket application. We have started preparing the configuration artifacts needed for our applications. As promised in chapter 2.4, we needed to put in place just a minimal amount of XML with an application class and a home page. Then we have continued our “first contact” with Wicket learning how to build a simple page with a label component as child. This example page has shown us how Wicket maps components to HTML tags and how it uses both of them to generate the final HTML markup. In the last paragraph we had a first taste of Wicket links and we have seen how they can be considered as a “click” event listener and how they can be used to navigate from a page to another.