Home > Java > A Maven Quickstart on Wicket, Spring and Hibernate

A Maven Quickstart on Wicket, Spring and Hibernate

Apache Wicket seems to gain popularity. At least it looks like more and more (large) organisations use Wicket in their (production) web applications.

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:

mvn jetty:run

… 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.

Let’s start

We will start with the maven project. In the pom.xml we see the folowing dependencies:

groupId artifactId version Note
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 1.8.0.7 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
  • src/main/webapp/ – Containing our css stylesheets / javascripts / images but NOT our Html files! Plus of course our WEB-INF/web.xml defining our Spring-Wicket web-application.

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:

  1. getHomePage() Returning the class of the homepage (an implementation of org.apache.wicket.markup.html.WebPage)
  2. 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.

<filter>
<filter-name>wicket.wicketSpringHibernateQuickstart</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>wicket.wicketSpringHibernateQuickstart</filter-name>
<url-pattern>/*</url-pattern>
</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.

That’s it! Have a look at the Apache Wicket website for more information, read a book of have a look at some examples.

Enjoy!

About these ads
Categories: Java Tags: , , ,
  1. Arnaud Brunet
    11/05/2011 at 07:20

    Hello,

    The archetype does not seem to work. I get the following exception :
    [ERROR] org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prol
    og.
    org.apache.maven.archetype.exception.ArchetypeGenerationFailure: org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in
    prolog. Nested exception: Content is not allowed in prolog.
    at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.generateArchetype(DefaultFilesetArchetypeGenerator.java:236)
    at org.apache.maven.archetype.generator.DefaultArchetypeGenerator.processFileSetArchetype(DefaultArchetypeGenerator.java:215)
    at org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype(DefaultArchetypeGenerator.java:130)
    at org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype(DefaultArchetypeGenerator.java:290)
    at org.apache.maven.archetype.DefaultArchetype.generateProjectFromArchetype(DefaultArchetype.java:75)
    at org.apache.maven.archetype.mojos.CreateProjectFromArchetypeMojo.execute(CreateProjectFromArchetypeMojo.java:185)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:227)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
    Caused by: org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in p
    rolog.
    at org.dom4j.io.SAXReader.read(SAXReader.java:482)
    at org.dom4j.io.SAXReader.read(SAXReader.java:365)
    at org.apache.maven.archetype.common.DefaultPomManager.addModule(DefaultPomManager.java:88)
    at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.processPomWithParent(DefaultFilesetArchetypeGenerator.java:698)
    at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.processFilesetProject(DefaultFilesetArchetypeGenerator.java:594)
    at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.processFilesetModule(DefaultFilesetArchetypeGenerator.java:515)
    at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.generateArchetype(DefaultFilesetArchetypeGenerator.java:206)
    … 23 more
    [INFO] ————————————————————————
    [ERROR] BUILD FAILURE
    [INFO] ————————————————————————
    [INFO] : org.apache.maven.archetype.exception.ArchetypeGenerationFailure: org.dom4j.DocumentException: Error on line 1 of document : Content is not a
    llowed in prolog. Nested exception: Content is not allowed in prolog.
    org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.

    org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.

    Regards,
    Arnaud

    • 18/05/2011 at 09:52

      Hello Arnaud,

      I don’t have any problems here on multiple machines. Can you tell me what maven version you use and which OS you are running.
      Do you have any specific settings in your settings.xml?
      You might want to temporary remove it and try it again (and perhaps clean or move your local repository).

  2. Arnaud Brunet
    19/05/2011 at 23:12

    Thanks for your response.
    I found the problem : my local repository was corrupt.
    I cleared it, and it’s work.

    Regards,
    Arnaud

  3. Evgenioni
    11/07/2011 at 01:19

    Hi, I’m newbie in Java Development and Wicket and I don’t know how to change the first testing example to even the second or the third one.
    All my workaround failed.

    Please help me with using you perfect examples cause it’s very important to me.

    • 12/07/2011 at 16:05

      Hi Evgenioni,

      My guide is written for people who already have java experience but sure I would like to help you out a bit. Can you give me specific errors or problems you experience?
      Maybe as a newbie it’s better to start reading a java book and perhaps a few chapters of the Wicket in Action book first and have them next to you when working on the examples.
      Try to find and understand the differences between the given examples.

      • Evgenioni
        26/07/2011 at 13:58

        Thank you for answering. I’ll start reading the java and wicket books. But it’s to difficult for me to find solution or article where could be included some different technologies.
        In my application I need to use PostgreSQL database for storing data, AJAX for dynamic information updates on the site.

        I’ve started to read Wicket Cookbook, but also will read Wicket in Actoin.

        Thank you.

  4. 16/07/2011 at 16:39

    There is a nice Wicket plugin for eclipse out there – qwickie which opens the view and its related controller simultatiously (when either one is clicked). It also has a handy outline view of code. When clicking on id’s the corresponding code will be opened in the other file (view-> controller, controller -> view).
    Be sure to check out these and other features of qwikcie from apache:

    http://code.google.com/p/qwickie

  5. danistroyer
    17/01/2012 at 05:03

    Hi! Thanks a lot for the tutorial!

    I’m trying to replicate the first example in a clean project and after setting all the configs files and everything ‘the same’ as yours (I’m using wicket + spring + hibernate), it displays this error:

    ContextLoaderListener
    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1688)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1533)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:525)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:507)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:124)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4701)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5260)

    The only difference that I see is that in your projects deployment assembly you have a persisted container reference, don’t know if this is the reason why the context is not being loaded.

    Appreciate any help.

    Thanks!

  6. Sanjay Patel
    26/05/2012 at 20:00

    Hi,

    I followed the instructions and kept my project name crystal360. I did mvn jetty:run and it ran successfully. When I try to to access http://localhost:8080/crystal360, I get below error.

    Access to the webpage was denied
    You are not authorized to access the webpage at http://localhost:8080/crystal360. You may need to sign in.
    HTTP Error 403 (Forbidden): The server refused to fulfill the request.

  1. 12/06/2011 at 06:48

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 209 other followers