A Maven Quickstart on Wicket, Spring and Hibernate
And why not?
- It’s open source (under the Apache licence)
- There is a large and active community
- There is no XML configuration
- There is good separation between logic (Java) and view (Html)
- It’s pure (OO) Java!
That last item tells me this is an ideal framework for Java developers like you(?) and me. If you’re familiar with other webframeworks like JSF of Spring MVC perhaps, you might have to switch a button in your mind though. Wicket is different in a few ways, you will notice that later.
A simple web application with just Wicket would probably not be sufficient in most cases. Usualy there is the need of a database and preferably we want to have a nice architecture with separated Dao-, Service- and front-end layers, where you can continue to use other frameworks in the backend. And, of course, we want Maven as our build environment.
In this blogpost I’ll show you how to quickly setup a Wicket application using Maven (2), Spring and Hibernate. In this case I use a HsqlDB file-database but other Hibernate configuration are easily Google-able.
I will explain the setup with an example application of which I have created a maven archetype. The application created by the archetype has actually done all the work for you, but keep reading if you want to know how.
Create the application
To create the example application execute the Maven archetype command like this:
mvn archetype:generate -DarchetypeGroupId=nl.iprofs -DarchetypeArtifactId=wicket-spring-hibernate-quickstart -DarchetypeVersion=1.3 -DarchetypeRepository=http://www.iprofs.nl/repository/ -DinteractiveMode=false -DgroupId=com.mycompany -DartifactId=myproject
The command will create a map with your demo application. Do this inside the map where you want to have it created, for example C:\myWorkspace\. Also you may want to change the last 2 arguments, groupId and artifactId to your own values.
After the archetype created your project you should be able to run it with the following command from within your application’s directory:
… and open your browser at http://localhost:8080/myproject (or whatever name you have given it).
Play around with the five different (growing) examples in the *web.examples packages. Be sure to have the corresponding parent in the WicketApplication class as you head to newer examples and uncomment the insertion of the userManager in the applicationContext once you are at the fourth example.
We will start with the maven project. In the pom.xml we see the folowing dependencies:
|org.apache.wicket||wicket||1.4.15||The core Wicket library|
|org.apache.wicket||wicket-spring||1.4.15||The integration of a Wicket application in Spring|
|org.apache.wicket||wicket-extensions||1.4.15||Extentions to the core Wicket with lots of perfect (markup) components out of the box. Not needed in a simple Hello World but comes in handy very quickly|
|junit||junit||3.8.2||For a simple unit test of our homepage, we might want a newer version here|
|org.springframework||spring||2.5.6||The core Spring library|
|org.springframework||spring-test||2.5.6||Spring library used for unit testing using Spring beans|
|org.hibernate||hibernate||3.2.6ga||Hibernate core library (3.2.6ga is a popular version)|
|hsqldb||hsqldb||188.8.131.52||The Hsql (file) database library|
|commons-dbcp||commons-dbcp||1.2.2||Used as the HsqlDB datasource|
|javax.servlet||servlet-api||2.5||Only needed for a handy lookup in our HsqlDB configuration in this example|
|log4j||log4j||1.2.14||Used for the logging in our application|
|org.slf4j||slf4j-log4j12||1.4.2||Used for formatting our logging.|
Now, our map structure should look familiar, like this:
- src/main/java/ – Containing our Java packages. In the web subpackages where we place our Wicket code we will see the Java files as well as the html files!
- src/main/resources/ – Containing our Hibernate mapping files (in this example we’re not using JPA annotations), the Spring applicationContext.xml and our HsqlDB files.
- src/test/java/ – Containing our unit tests
The Spring configuration
In the applicationContext.xml we will describe our Spring configuration. It will contain the following beans:
- wicketApplication. This is the root of the Wicket application, it is associated with an instance of ‘the’ WicketServlet, handling all requests for Wicket.
- dataSource. The source to our data using the (jdbc) driver. (in this case to our Hsql database)
- transactionManager. A manager (for the service layer) handling the (database) transactions, implemented by Spring’s HibernateTransactionManager
- managerTemplate. A template bean (parent) for our managers (servicelayer). This template is a Spring AOP proxyFactoryBean which we’ll give an interceptor (another Spring bean) for transations using the transactionManager.
- sessionFactory. A factoryBean for the Hibernate sessions. This bean, implemented by Spring’s LocalSessionFactoryBean uses the dataSource bean and gets the Hibernate mappingfiles and other Hibernate proberties
- Dao- and manager-beans. These backend interfaces can be injected in the wicketApplication bean so we will be able to reach the backend from within our front-end Wicket code.
The Hibernate configuration
The Hibernate configuration is mostly done in the Spring configuration as mentioned before. Look in the applicationContext.xml and the files in src/main/resources/hibernatemappings/ for more details.
As I don’t want to (and can) get into details about Hibernate itself I suggest to Google around for more information.
The Wicket configuration
For a simple Wicket application like this, there is not much to configure. As we saw in the Spring configuration we’ll need a wicketApplication bean. This bean should be an extention of the org.apache.wicket.protocol.http.WebApplication class which is used by the (single) WicketServlet. The only 2 methods we have to implement here are:
- getHomePage() Returning the class of the homepage (an implementation of org.apache.wicket.markup.html.WebPage)
- init() An initialisation method called during startup. Here it is possible to create bookmarkable pages for example or authorization. You can leave it empty for now.
It is good practice to create a bookmarkable pages. This means giving a logical name to a page (which is allways a class extended from org.apache.wicket.markup.html.WebPage) so you can enter the URL to a page manualy (or add it to some third party menu). You can do this in the WicketApplication class by calling the mountBookmarkablePage(path, classfile). As parameters you’ll give a (web)path to the page, for example “/homepage”, or “/admin/users”, and the class of that page (for example HomePage.class).
Since you have implemented the getHomePage() method, Wicket knows which page to show you when you’ll enter the URL to your application (being the WicketServlet) in your browser.
The web.xml configuration
As mentioned before, there is a single WicketServlet handling all requests for Wicket(pages). In the web.xml you will see that we only need a Wicket filter and corresponding filter-mapping.
You will notice that we use the org.apache.wicket.spring.SpringWebApplicationFactory (from our wicket-spring dependency) as a factory class instead of directly pointing to our WebApplication class. This is where Wicket and Spring come together. the SpringWebApplicationFactory will look for a bean with an implementation of Wicket’s WebApplication and forwards the request to Wicket.