Monday, November 14, 2011

Spring 3 with Hibernate, Maven 2 and Apache Tiles

In this post I show you how to create a java mavenized application using Spring MVC 3 and Hibernate.
I am using Springsource Tool Suite (STS) that is an Eclipse-like IDE that semplifies the development of Mavenized applications with Spring framework.

Once created a new Maven Web project through the wizard, we need to modify the pom.xml file that is the Maven configuration file that allows us to define the application name, developers, company informations, etc.
But, most important, it allows us to define the libraries required to develope the application and some Maven plugins, such as the one that builds and compiles the application.


In the first part of the pom file we can find information such as the application name, version, and the developers that work on it.
Then, we have the dependencies, that are the libraries required to develop the application. Among these, there are Junit and Mokito (used for testing purposes), log4j used for logging purposes, Apache Tiles that is the apache library to create structured web pages made of "jsp fragments" (I will show you later how to define pages based on tiles). Then we have the validation library used by Hibernate to validate data inserted on web page forms.
We can then find a set of dependencies for the Spring framework (core, expressions, bean, aop, context, web, test, orm) used to control all the application tiers. After these, Hibernate library used for the Object Relational Mapping and query the database. Then we have AspectJ that is used to define aspects to control crosscutting concerns of the application.
Lastly I have defined the build plugin of maven that it uses to build the application and package it in the format defined in the first part of the pom.


Now that we have defined the libraries needed for the development of our application, we can define the web.xml file that handles the requests from the clients and defines other important files for the application management.


From the web.xml file we can see that the application is managed by Spring framework.
We have defined 2 listeners:

  • the first is the Log4jConfigurationListener that loads the log4j configuration file which location is defined in the context-param named  "log4jConfigLocation" and its location is inside the devconn folder in the root path of the application server; 
  • the second listener is the ContextLoaderListener that is used by Spring to load its configuration files. The associated context-param, loads a list of spring configuration files: applicationContext-aspect.xml in which I have defined some aspects that manage crosscutting concerns; applicationContext-data.xml in which I have defined beans that have to do with database (datasource, hibernate session factory, and dao classes); applicationContext-mail.xml which defines beans to send email. 
Under the definition of listeners, we find the definition of a servlet managed by the Spring DispatcherServlet  which is associated to another spring configuration file that defines the beans that manage the user requests and other web utilities who's name is spring-mvc-servlet.xml
Lastly I have defined the taglib location for the definition of tiles.

The next step is the definition of the spring-mvc-servlet.xml that manages the user requests: 


First of all we can see the import od XML Schema Definitions for the different Spring components used in the configuration file. Then we have the definition of the location for the static resources such as images, css... . 
Then we define that the mvc components are annotation-driven, it means that there is not the definition of Spring Controller beans in xml configuration files but those components are defined using Spring annotations (I will show you later). If we want automatic generation of proxies, we will use the tag <aop:aspectj-autoproxy/> through the AOP namespaces. 
After the definition of base-package we have the definition of  two beans about the configuration (which defines the configuration file) and resolution of Tiles. 
Lastly we have the definition of some beans about the message bundle and internationalization

The next step is the definition of a Spring Controller that is the handler for a user request, and I show you the controller for the user registration process: 


The first instruction in the above picture is the @Controller annotation that defines this class as a Spring controller. The second instruction defines the attributes that will be added to the HttpSession. 
Then we have another annotation, that is the @RequestMapping annotation and defines the path at which this controller will be called. 
The controller has three instance variables; these are injected to the controller as dependencies at construction time by the Spring framework that searches on his context configuration files for  beans definitions that have the same type and name of the one required by the controller. The constructor has the @Inject annotation that asks Spring to find and inject the required beans. 
Then we have two methods both preceded by the @RequestMapping annotation that defines the Http request method, and the first one answers to a GET request while the second answers to a POST request at the same address, that is the one defined above.
The first method inserts some attributes into the model object such as a new DevProfile object that has to be filled by the registration form and some other attributes containing objects needed to define the registration form. 
The second method receives the registration form, and has some input parameters related to the filled form. We can see the @Valid annotation before the DevProfile object that is used for validation purposes based on rules defined in the DevProfile entity class. If one or more of these validation rules is not satisfied the response returns to the input page showing the errors, else it saves the DevProfile into the database and after  sending a registration confirmation email, shows a login page as a result of a successful registration. 
Both the methods return a String that represents the name of the view to be showed. 
Spring searches the view definition corresponding to the returned String through the TilesViewResolver defined precedently in the spring-mvc configuration file. 

The next step is the definition of the tiles and the corresponding views made of jsp fragments. 


As we can see from the above image, every tile definition is made of many jsp fragments and other attributes such as CSS files and the page title. The first definition is called baseLayout and defines exactly a base layout that the other definition extend and modify based on their purposes. Continuing the analization of the baseLayout definition, we see that it defines a page template with a jsp page (that I show you later). The template is the definition of a page layout, that we can see in the picture below: 


The attributes added on the definition are the page title, the css style for the page content, the header of the page called top, the left side, the body called content and the footer.
The other tiles definitions, as I wrote earlier, extend this baseLayout definition and override values based on the content that has to be displayed on the resulting page. 

I show you now the jsp page template:


First of all at the top of the page there is the import of the tiles tag lib that we defined in the web.xml file.
As we can see, the image above also illustrates the attributes that we have defined precedently in the tiles configuration file. Inside the head tag, we have the page title attribute and the import of the css defined in the tiles configuration file and other default css files. 
Inside the body tag we can find the jsp fragments top, left, content and bottom. 

Now I show you the body part of the registration tile, that contains the registration form. 


At the top of the page we have the tag libs import (jsp core, spring, and spring form). Using the form tag of the spring form tag library we then define the registration form in which can find the modelAttribute that is the new DevProfile object we inserted into the model object in the RegistrationController and define the HTTP method attribute as POST that is used by the framework to call the method we've defined in the controller and annotated with the RequestMapping annotation with a POST value for the method. attribute. 
The message tag of the spring tag lib is used to show a label which value to be displayed is read from the message bundle defined in the spring context file. 
I have separated the personal information and account information with two fieldset. The first one contains personal informations such as name, surname, gender, date of birth in which name and surname are simple input text fields, while gender and birthday fields are made with spring select tags that use some of the attributes inserted into the model object on the RegistrationController class. 
The second fieldset contains account informations email and password for the user that wants to register. 
You can also find spring form errors tag for every field that requires validation. If the values inserted in the field does not pass the validation, the tag shows the error under that field. 
Lastly we have the confirmation button that once clicked sends the request to the RegistrationController's method. 


Now I show you the definition of a fragment of the DevProfile entity class that is a simple java POJO with validation annotation over some fields through which it is possible to manage validation on web forms.


As you can see, with simple annotations over the fields we can control form validation. There is not the need to tell you what the annotations mean because you can just read these and understand on your own that the name’s size must be between 3 and 25, Gender could not be empty, etc…

Now is the time to introduce AOP with Aspectj to control crosscutting concerns such as logging. I have, indeed, used an aspect to manage logging on controllers.
First of all, as you remember, in the web.xml I defined an applicationContext-aspect.xml configuration file into which I have defined aspect beans. Let's see the configuration file: 


The picture above shows the configuration of a bean used as an aspect for logging purposes.
We define aspects using the spring aop XML Schema components. Inside the <aop:config> tag we define the different components of an aspect: the pointcut tag defines where the advice should be called, in my case the expression “execution (* com.faeddalberto.devconn.controller.*.*(..)) “  tells aspectj to call the advice every time a method with any number of parameters of the classes in the com.faeddalberto.devconn.controller package is called. After the definition of the pointcut we find in the configuration the definition of the loggingAspect with two advices, one before and one after the execution of an application method, called joinpoint. We can obtain the same result using one only advice, called around that is called before entering the joinpoint method and after exiting it.
Let’s now give a look at the class defined as aspect:


 As you can see it is a simple Java class with two methods used for logging purposes. Both methods have a parameter that is JoinPoint. It has some utility methods that give us the opportunity to figure out which is the class that has been called and its method name and some other utilities.

Another application configuration file that I listed in the web.xml file is the applicationContext-data.xml that is used to define database related beans and Hibernate session factory bean. Let’s give it a look:



The first important thing in this context file is the jndi-lookup tag: it searches for a component with a name defined in the jndi-name attribute using jndi lookup. We are using this way to find and define the dataSource that configures the database connection.
Another important bean definition is the sessionFactory, that is the Hibernate most important bean to which we inject the datasource defined earlier and a list of mapping resources files (Object Relational Mapping), I am showing only two of the orm files I have in my project. We than define hibernate properties: I am only defining the dialect to be used to query the database. We know that in the java code we use HQL that is Hibernate Query Language to define queries; these queries are then translated using the dialect here into SQL to query the database in a language understandable by it.
After the definition of the session factory we define the transaction manager injecting the session factory bean.
Lastly I show you the definition of two beans, that are the DAO classes for two entities, into which we can find the methods used to perform CRUD operations.

In the next picture I’ll show you the ORM file for the DevProfile entity:



In the picture above I am mapping the DevProfile class to the profile database table defining the table columns associated with the java fields, the corresponding data type and the relations with other database tables mapped to other java classes using one-to-one or one-to-many or many-to-one tags and set tag to define a collection of related columns.

 The next part of the application that I want to show you is the implementation of DAO, let's start:


In the picture above we have the interface that lists the main operations on entities. The <T> is a placeholder for the type you pass in. In other words, whatever Tis when you declare the interface, that's what you can use with methods. Let's give a loot at the implementation of this interface: 


The picture above, shows the IDAO implementation, I called it AbstractDao because it is a common implementation that would be extended by the entities DAOs as needed. The EntityDAO will then have a constructor with 3 parameters: tableName, orderFieldName and entityClass. The methods in this class are simple methods that execute the Hibernate operations to Create, Read, Update, Delete, Flush, FindById, Merge, etc... 

Next I show you the extended DAO for the DevProfile entity: 


In the image above, I have created the DevProfileDao to execute the previous methods on the DevProfile entity, the only thing I did is creating a constructor passing the parameters to the super (AbstractDao) and if I need any other query, I do create new methods in this class. 

Next I show you the unit test for the RegistrationController: 


Finally I show you the registration page and the login page of the application:


Next is the registration page with error fields: 


The next picture is the login page, showed when registration is successfull: 





3 comments:

  1. This article is excellent, I got to know few new things with this article, Can you please share source code for the above example

    Thanks
    Kris

    ReplyDelete
  2. Hi Kris, thanks for your comment and your compliments.
    I am sorry, I can't give you the full example code because I am still working on it and adding a lot of new code and functionalities...
    To make the example work, most of the code is on the post picures.

    Thanks,

    Alberto

    ReplyDelete
  3. Say please, what is a reason about you add "final" in any "catch" in AbstractDao class, and no add in other "catch"?
    Why you do not add "final" in all "catch" in AbstractDao class?

    Thanks

    ReplyDelete