Tuesday, December 13, 2011

Send Email in Spring 3 (Spring MVC) with Gmail

today i have prepared a sample application that demonstrate how to develop a web application to use Gmail server to send email with Spring MVC 3.

this application will display you an email submission form where you can type the email message body, email header and the receiver email address. once those fields are filled, you can press send email button to send the newly created email using your email account (this is configured in the application configuration files and  we are going to discuss it in few minutes)

i have used the Spring Framework inbuilt mail package for sending email rather than using any other third party module. the below mentioned technologies has been used to develop this application.some of the main/core technologies are mentioned as follows.


  • Spring MVC 3 and Spring Framework inbuilt mail package
  • Apache Maven (version 03)
  • SLF4J logging framework
  • JSTL tag libraries


the below screenshot shows your the project directory structure of this application



we will look at each file in detailed with its duty and the responsibility towards this application.


index.jsp

this is a simple HTML page (no any jsp tags or other java code pieces - even if this is named as jsp) with a simple anchor tag. it directs the user to the email sending form upon user click.

<html>
<body>
<h2> <a href="/email/emailForm">Load Email Form</a></h2>
</body>
</html>



after click the anchor tag it will make the /email/emailForm URL call. the URL call will redirects to the Spring MVC DispatcherServlet as mapped in the web.xml file.

web.xml file

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">


    <display-name>Archetype Created Web Application</display-name>

    <context-param>
        <param-name>log4jConfigLocation</param-name><param-value>/resources/log4j.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>email</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>email</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

</web-app>


you can see that we have mapped all the user requests (URL requests) to the Spring MVC DispatcherServlet using web.xml file. In addition, we have used the web.xml file to do required configuration for the logging framework (either log4j or slf4j ). you can see that the dispatcher servlet name is email (as mentioned in the web.xml).


email-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- this will scan the @Component models defined in the given package (including sub packages) and it will automatically create instances.
         if you have used @Component annotation, it is not required to define the beans  in the XML configuration files -->
    <!-- Discover POJO @Components -->
    <!--<context:component-scan base-package="org.convey.registration" />-->

    <import resource="applicationContext.xml"/>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>


    <bean id="handlerMappingC"
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property
                name="mappings">
            <props>
                <prop
                        key="/emailForm">
                    emailController
                </prop>

                <prop
                        key="/sendEmail">
                    emailController
                </prop>

            </props>
        </property>
    </bean>


    <bean id="emailController" class="org.convey.example.controller.EmailController"/>

</beans> 
  

it will find and call the relevant controller based on the relevant url mapping done inside the email-servlet.xml . it will find that the emailController bean id is responsible for handling the /emailForm url mapping. emailController bean id is referring to the EmailController class. then it will find the EmailController instance for delegating the user request to the relevant method.


EmailController

package org.convey.example.controller;

import org.convey.example.email.EmailSender;
import org.convey.example.model.EmailMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import java.util.Map;


/**
 * $LastChangedDate:  $
 * $LastChangedBy:  $
 * $LastChangedRevision:  $
 */
@Controller
public class EmailController {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("emailConfiguration.xml");
    EmailSender emailSender=(EmailSender)context.getBean("emailSenderBean");


    final static Logger logger = LoggerFactory.getLogger(EmailController.class);


    @RequestMapping(value="/emailForm",method= RequestMethod.GET)
    public ModelAndView displayEmailForm(Map<String, Object> map){

        logger.debug(" setting up the Email form ");

        ModelAndView view=new ModelAndView("EmailFormView");

        //setting up the  required parameter value in the request scope for CommandName parameter
        map.put("email", new EmailMessage());

        return view;

    }



    @RequestMapping(value="/sendEmail",method= RequestMethod.POST)
    public ModelAndView sendEmailUsingGmail(@ModelAttribute("email")EmailMessage email){


        logger.debug(" ********************* ready to send the email **********************");
        logger.debug(" receiver email address [{}]", email.getReceiverEmailAddress());
        logger.debug(" email subject [{}]", email.getSubject());
        logger.debug(" email body [{}]", email.getMessageBody());

        ModelAndView view=new ModelAndView("EmailView");

        view.addObject("emailAddress",email.getReceiverEmailAddress());
        emailSender.sendEmail(email);
        logger.debug(" ********************* email was sent **********************");

        return view;

    }


}


as you can see that in the EmailController , displayEmailForm() method is responsible for handling the /emailForm request. (that is obviously GET request)

displayEmailForm() will display the email sending form page (jsp view) to the user. EmailFormView is a JSP page and that contains the required html input fields for composing the email message. the viewResolver defined  in the emai-servlet.xml can resolve this logical view name (EmailFormView) to the actual physical view name(EmailFormView.jsp).  Inside this displayEmailForm method, an instance of EmailMessage is created (referred as email) and put it in the request scope. this instance will be used by the email sending form for populating the user input form data when the submission is made. (you can later see it in the CommandName attribute in form)

EmailFormView.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
<head><title>Email Form</title>
</head>
<body>

<form:form commandName="email" method="POST" action="sendEmail">

    <p>Email Form </p>
    <br/><br/>

    Receiver Email
    <form:input path="receiverEmailAddress"/>
    <br/><br/>

    Subject
    <form:input path="subject"/>
    <br/><br/>

    Message Body
    <form:input path="messageBody"/>
    <br/><br/>

    </br>
    <input type="submit" value="Send Email" />

</form:form>

</body>
</html>



CommandName attribute is referring to the instance of EmailMessage (created in displayEmailForm() and referred as email) for populating the form data inputs when the form is submitted. form will be submitted to the URL /sendEmail . the relevant controller method will be found and the submission request will be delegated to the relevant method. sendEmailUsingGmail() method available in the EmailController class is responsible for this submission  request. then it will compose the message and send the email with the Gmail server.


EmailSender.java
package org.convey.example.email;

import org.convey.example.model.EmailMessage;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

/**
 * $LastChangedDate:  $
 * $LastChangedBy:  $
 * $LastChangedRevision:  $
 */

public class EmailSender {


    private MailSender mailSender;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }


    public void sendEmail(EmailMessage emailMessage){

        SimpleMailMessage message = new SimpleMailMessage();

        message.setTo(emailMessage.getReceiverEmailAddress());
        message.setSubject(emailMessage.getSubject());
        message.setText(emailMessage.getMessageBody());
        //sending the message
        mailSender.send(message);

    }


}

the EmailSender class is used to send the email with the provided EmailMessage object. this class uses the  email server settings provided in the emailConfiguration.xml  to send the email.

EmailMessage.java

package org.convey.example.model;

import org.springframework.stereotype.Component;

/**
 * $LastChangedDate:  $
 * $LastChangedBy:  $
 * $LastChangedRevision:  $
 */
@Component
public class EmailMessage {


    private String receiverEmailAddress;
    private String subject;
    private String messageBody;


    public void setMessageBody(String messageBody){

        this.messageBody=messageBody;
    }

    public String getMessageBody(){

        return this.messageBody;
    }

    public void setReceiverEmailAddress(String receiverEmailAddress){

        this.receiverEmailAddress=receiverEmailAddress;
    }

    public String getReceiverEmailAddress(){

        return this.receiverEmailAddress;
    }


    public void setSubject(String subject) {

        this.subject=subject;
    }

    public String getSubject(){

        return this.subject;
    }


}


EmailMessage class is used to represent the email message. it contains Message properties with public getters and setters.


emailConfiguration.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com" />
        <property name="port" value="587" />
        <property name="username" value="abanstest@gmail.com" />
        <property name="password" value="abanstest123" />

        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">true</prop>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.smtp.debug">true</prop>
            </props>
        </property>
    </bean>

    <bean id="emailSenderBean" class="org.convey.example.email.EmailSender">
        <property name="mailSender" ref="mailSender" />
    </bean>
</beans>

this file contains the email server connection details that are required to make a connection with the email server.

log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

    <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%x] %c{1} %m%n" />
        </layout>
    </appender>

    <appender name="FileAppender" class="org.apache.log4j.FileAppender">
        <!-- the log file will be available inside the logs directory of the tomcat installation. the name of the log file is sample.log -->
        <param name="File" value="../logs/sample.log"/>
        <!-- the log will contains the log messages started from the INFO level..(info or less) -->
                <param name="Threshold" value="INFO"/>
     <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%x] %c{1} %m%n" />
        </layout>
    </appender>

   <root>
       <level value="DEBUG" />
        <appender-ref ref="ConsoleAppender" />
        <appender-ref ref="FileAppender" />
    </root>

</log4j:configuration>

this is the logging framework (either log4j or slf4j) configuration file.


the source code is available in the following GIT repository.

git@github.com:chathurangat/spring-email.git

hope this will helpful for you
Chathuranga Tennakoon
chathuranga.t@gmail.com

Monday, December 12, 2011

Jquery Form Validation

I have developed simple php based form validation example to demonstrate the jQuery based fom validation.
please set up the following files in your WAMP/LAMP/XAMP server.


index.php
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

    <!--since we are using jquery, the jquery fram,eworkj should be inherited-->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

    <!--jquery.validate.js file should be included because we are going to validate the form fileds based on the jquery validation framework -->
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.js"></script>

    <!--Validation.js is the centralized javascript file where the all javaScript and Jquery functions have been implemented-->
    <script type="text/javascript" src="validation.js"></script>


    <title>Chathuranga Tennakoon</title>
</head>
<body>


<form id="sample_form" name="sample_form" method="post" action="">

    First name <input id="first_name" name="first_name" type="text"/><br/>
    Age <input id="age" name="age" type="text"/><br/>
    Email <input id="email" name="email" type="text"/><br/>

    <input type="submit" name="submit" id="submit" onclick="validateAndSubmit()" />

</form>


<div id="submitHandlingMessage">


</div>

</body>
</html>


validation.js

/*
 Author:Chathuranga Tennakoon
 Email: chathuranga.t@gmail.com
 Web : http://chathurangat.blogspot.com
 */

function validateAndSubmit(){

    $().ready(function() {

        $("#sample_form").validate
            ({
                rules:
                {
                    first_name: "required",
                    age:{
                        required:true,
                        number:true
                    },
                    email: {
                        required: true,
                        email: true
                    }
                },
                messages:
                {
                    first_name: "First Name is required",
                    age: {
                        required:"Age is required",
                        number:"Age is invalid"
                    },
                    email:{
                        required:"Email is required",
                        email:"Please neter valid email"
                    }
                },

                submitHandler: function(form) {

                    //submit handler function will invoke if al the data fields are validated properly
                    $.post('requestHandler.php', $("#sample_form").serialize(), function(msg) {
                        $('#submitHandlingMessage').html(msg);
                    });
                }

            });
    });


}//validateAndSubmit


requestHandler.php

<?php
/*
Author:Chathuranga Tennakoon
Email: chathuranga.t@gmail.com
Web : http://chathurangat.blogspot.com
*/

$message = "Submitted Data as follows";

$message = $message." Name ".$_POST["first_name"]."<br/>";
$message = $message." Age ".$_POST["age"]."<br/>";
$message = $message." Email ".$_POST["email"]."<br/>";


echo $message;



?>

Saturday, November 19, 2011

How to add Jar files(dependencies) to your local Maven Repository using linux vi editor

sometimes you may required to download some jar files(dependencies) manually from the remote servers  and add them to your local maven repository. the following command can be used in the linux vi editor for manually adding the jar file for your maven local repository.

mvn install:install-file -Dfile=/home/chathuranga/spring-modules-validation-0.9.jar -DgroupId=org.springmodules -DartifactId=spring-modules-validation -Dversion=0.9 -Dpackaging=jar -DgeneratePom=true


you are required to change the parameter values appropriately based on your dependency type(jar file type)

hope this will help for you!


regards
Chathuranga Tennakoon
chathuranga.t@gmail.com


Spring MVC Form Data Validation with Hibernate annotations

text here

Spring MVC Form Data Validation with springmodules annotations

text

Friday, November 18, 2011

CAS(Centralized Authetication Service) - User Authentication using MySQL Database

Today i am going to show you how to configure the CAS server to authenticate users using MySQL database. if you do not know about CAS server, you can refer my initial post on Introduction to CAS Server. 

first execute following SQL commands to create the database and tables that are required in the user authentication process.

/*  command to create the database */
create database cas_login;

/* command to create the table */
create table user_login(
userID int AUTO_INCREMENT PRIMARY KEY,
username varchar(100),
password varchar(100)
);

/* insert the fisrt value to the table. password value is md5 encrypted value of chathuTest */

insert into user_login values('','chathuranga','434442e63b1869afd706c947072ecb44'); 

now the required database (with tables) has been established in your databse server and it is the time to make necessary configurations in the cas server.

1.pom.xml 

add the following dependency declarations for your pom.xml file inside the cas-server-webapp module. (/cas-server-webapp/pom.xml)

   
    <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.0.5</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>cas-server-support-jdbc
            </artifactId>
            <version>${project.version}</version>
        </dependency>


mysql-connector-java - mysql connector for making a connection from Java  to  MySql

cas-server-support-jdbc - the module that is developed to provide JDBC authentication for CAS server.

2.deployerConfigContext.xml

Add the following AuthenticationHandler in the list of Authentication Handlers defined inside the /cas-server-webapp/src/main/webapp/WEB-INF/deployerConfigContext.xml file.

  • AuthenticationHandler Declaration

<bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
                    <property name="tableUsers"><value>user_login</value></property>
                    <property name="fieldUser"><value>username</value></property>
                    <property name="fieldPassword"><value>password</value></property>
                    <property name="dataSource" ref="dataSource"/>
                    <property name="passwordEncoder" ref="md5PasswordEncoder" />
                </bean>

this bean declaration should be placed inside list under the  the authenticationHandlers  property as follows.    

<property name="authenticationHandlers">
            <list>
 
<bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
                    <property name="tableUsers"><value>user_login</value></property>
                    <property name="fieldUser"><value>username</value></property>
                    <property name="fieldPassword"><value>password</value></property>
                    <property name="dataSource" ref="dataSource"/>
                    <property name="passwordEncoder" ref="md5PasswordEncoder" />
                </bean>

            </list>
        </property>

tableUsers - the value should be the database table where the username and password fields exist

fieldUser - the name of the column that contains the username

fieldPassword -  the name of the column that contains the password

dataSource - the database name and other db configuration details. it says that refer to some other bean whose ID named as "dataSource". we will look at this bean few seconds later.

passwordEncoder - this refers to the required bean used for encoding the password that is entered by the user.


  • dataSource bean declaration
     place the following bean declaration in the deployerConfigContext.xml under the beans declaration. (<bean> </beans>)


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:mysql://localhost:3306/cas_login</value>
        </property>
        <property name="username"><value>root</value></property>
        <property name="password"><value>abc123@#</value></property>

    </bean> 

driverClassName - JDBC Driver class name. here we are going to connect to the MySQL server.

url - the url contains of three parts as described below.
jdbc:mysql://server:port/databaseName

  • server  - IP address of the serverwhere your MySQL server is running (in my case localhost)
  • port - the port number that is allocated to run MySQL server (default is 3306)
  • databaseName - the name of the database where the user credentials are stored.(in my case "cas_login" is the database name that i have given)
 username - username that is used to login to the database server

 password - the password associated with the given username (above username)


  • passwordEncoder declaration
add the following passwordEncoder bean declaration in the /cas-server-webapp/src/main/webapp/WEB-INF/deployerConfigContext.xml file.

    <bean id="md5PasswordEncoder"
        class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
        <constructor-arg index="0" value="MD5" />
    </bean>


if you have done all above configurations, now it is the time to build a release of the CAS server that provides support to authenticate users with MySQL database. it is good to compile and build all modules of the CAS server rather than building only the cas-server-webapp module. 

you can use the following command to build the CAS server. (assume that you are in the root of the CAS-Server directory. In my case, the root is /home/chathuranga/Projects/cas-server-3.4.11)

mvn clean install -DskipTests

Once the build process is succesfully completed, deploy the cas.war file in the webapps directory in your tomcat server. the following command can be used to deploy the cas.war file using terminal.

cp  cas-server-webapp/target/cas.war $CATALINA_HOME/webapps/

now you can check whether the cas server my sql authentication is working. try to login to CAS server using following username and password. if the login is successful, congradulations it is working. :) otherwise enable the tomcat logs and check where the failure is.  

username: chathuranga

password:  chathuTest



Hope this will helpful for you!

thanks and regards
Chathuranga Tennakoon
chathuranga.t@gmail.com

Sunday, October 30, 2011

Spring MVC Form data validation with Spring-Modules Annotations

this post will guide you how to validate form data based on the annotations provided in the spring-modules framework.In addition, this will show you how to bind form data to a data model and how to use EL(Expression Language) in Spring web application.

the folllowing technologies have been used to prepare this post. 

Spring MVC 3
Maven building tool
Spring Form tag libraries
Intelli J IDEA IDE
SLF4J logging framework
SpringModules Framework for Annotation based data validation

the following diagram shows you the standard directory structure  of this sample web application. (it is importnat to note that you are not required to have DAO, Service and Validation sub packages under the org.conver.registration package for this web application. i composed this post and took this screenshot while i was enhancing this simple tutorial to integrate data access using hibernate and JPA. you will get that example in my future post. :) )




now we can see the content of the each file in detailed as follows.


1. web.xml file


    Spring3-SpringModules-Annotation based Data Validation-Example

    
        index.jsp
    

    
    
        log4jConfigLocation/resources/log4j.xml

    
    
        registration
        
            org.springframework.web.servlet.DispatcherServlet
        
        1
    

    
        registration
        /
    


    
        
            org.springframework.web.context.ContextLoaderListener
        
    




In web, XMl you are required to notedown the following points.

*. log4j.xml file configuration for adding logging framework support(either log4j or slf4j for this project)

*.Spring MVC Front Controller Mapping known as MVC dsipatcher servlet

2. the below JSP page represents the user registration view that is displayed to the user for getting the required user inputs.

userRegisterView.jsp file

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
<head><title><spring:message code="registration.page.name"/></title>
</head>
<body>

<form:form commandName="user" method="POST" action="register">

    <p><spring:message code="registration.form.header"/> </p>
    <form:label path="username"><spring:message code="registration.label.username"/></form:label>
    <form:input path="username"/>
    <form:errors path="username"/>
    <br/>

    <form:label path="password"><spring:message code="registration.label.password"/></form:label>
    <form:password path="password"/>
    <form:errors path="password"/>
    <br/>

    <form:label path="email"><spring:message code="registration.label.email"/></form:label>
    <form:input path="email"/>
    <form:errors path="email"/>
    </br>
    <input type="submit" value="register" />

</form:form>

<spring:message code="registration.page.copyright.information"/>

</body>
</html>

Important things to note
JSTL tag libraries has been used
spring message binding with external property files



once the user press the register button, it will submit the data using POST method to the relevant controller method that is dedicated for the register URL pattern.In addition, it will bind all the user input for the model object provided as the user in the request scope.  you can see the main controller as below.

3. UserAdministration.java file
package org.convey.registration.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.convey.registration.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

/**
 * $LastChangedDate:  $
 * $LastChangedBy:  $
 * $LastChangedRevision:  $
 *
 *  Author: Chathuranga Tennakoon ( chathuranga.t@gmail.com  tel: 009475961039 )
 */
@Controller
@RequestMapping("/userRegistration")
public class UserAdministration {

    final static Logger logger = LoggerFactory.getLogger(UserAdministration.class);

    @Autowired
    private Validator validator;

    @RequestMapping(value="/register", method = RequestMethod.GET)
    public String displayUserRegistrationForm(Map<String, Object> map){

        logger.debug(" request is for displaying the user registration form ");

        //setting up the  required value in the request scope for CommandName parameter
        map.put("user",new User());
        // InternalViewResolver will resolve the logical view name to the actual physical views name
        return "userRegisterView";
    }


    @RequestMapping(value= "/register" , method = RequestMethod.POST)
    public ModelAndView registerNewUser(@ModelAttribute("user")User user, BindingResult result){

        logger.debug(" Form data retrieved from the user registration page and Data validation starts ");

        String password=user.getPassword();
        String username=user.getUsername();
        String email=user.getEmail();

        //here we are using slf4j for logging
        logger.debug(" retrieved username is [{}] ",username);

        ModelAndView view=new ModelAndView("userRegistrationSuccessView");
        // the below parameters can be access in userRegistrationSuccessView jsp page using Expression language (EL)
        view.addObject("password",password);
        view.addObject("username",username);
        view.addObject("email",email);

        validator.validate(user, result);

        logger.debug(" has form errors?  [{}] ",result.hasErrors());

        if (result.hasErrors()) {

            logger.debug(" errors occurred during the validation process ");

            ModelAndView userRegisterFormView=new ModelAndView("userRegisterView");

            return userRegisterFormView;
        }
        else{
            logger.debug(" all data was properly validated with no errors ");
            return view;
        }

    }


} 

the below class is the model class called User. you can see that we have used the validation annotations provided in the springmodules framework for validating the user inputs captured from the user interface given above(userRegisterView.jsp)

4.User.java file (data model class)
package org.convey.registration.model;

import org.springframework.stereotype.Component;
import org.springmodules.validation.bean.conf.loader.annotation.handler.Email;
import org.springmodules.validation.bean.conf.loader.annotation.handler.Length;
import org.springmodules.validation.bean.conf.loader.annotation.handler.NotBlank;

/**
 * $LastChangedDate:  $
 * $LastChangedBy:  $
 * $LastChangedRevision:  $
 *
 * Author: Chathuranga Tennakoon ( chathuranga.t@gmail.com  tel: 009475961039 )
 */
@Component
public class User {

    /* all validation error messages has been defined inside the messages.properties file. */
    @NotBlank
    @Length(min = 5, max = 20)
    private String username;

    @NotBlank
    @Length(min = 5, max = 20)
    private String password;

    @NotBlank
    @Email
    private String email;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

since we have used @Component annotation for the User class (POJO class), it is not required to define the bean in the xml files. since we have declared
    <context:component-scan base-package="org.convey.registration" />
in the xml configuration file, it will automatically discover the classes (that are inside the above package or its sub packages) with the @Component annotations  and initiates their instances in the spring web container at the web application loading time.


you can see that we have used spring modules annotations for the user input validation. all the validations messages have been defined inside the messages.properties file. that can be shown as below.


5. messages.properties file
#User Registration From Page
registration.page.name=User Registration Page
registration.form.header= User Registration Form
registration.label.username=Username
registration.label.password=Password
registration.label.email=Email Address
registration.page.copyright.information=Developed by chathuranga.t@gmail.com (tel 0094759610139)


#User Registration Form Validation messages
User.username[not.blank]=Username is required
User.username[length]=Username length should be minimum {1} to maximum {2} Characters.
User.username[regexp]=Username can contains only lowercase and uppercase characters

User.password[not.blank]=Password is required
User.password[length]=Password length should be minimum {1} to maximum {2} Characters.

User.email[email]=Invalid characters for the email
User.email[not.blank]=Email is required


6. applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- the below bean is configured to define external property file for defining property values for the application.
           the following bean is used for configuring a resource bundle for this application based on different locales-->
    <bean id="messageSource"
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="classpath:properties/messages" />
    <property name="defaultEncoding" value="UTF-8"/>
    </bean>

</beans>

7.registration-servlet.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- this will scan the @Component models defined in the given package (including sub packages) and it will automatically create instances.
         if you have used @Component annotation, it is not required to define the beans  in the XML configuration files -->
    <!-- Discover POJO @Components -->
    <context:component-scan base-package="org.convey.registration" />

    <import resource="applicationContext.xml"/>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>


    <bean id="handlerMappingC"
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property
                name="mappings">
            <props>
                <prop
                        key="/userRegistration/*">
                    userAdministrationController
                </prop>
                <prop
                        key="/userRegistration/register/*">
                    userAdministrationController
                </prop>

            </props>
        </property>
    </bean>


    <bean id="userAdministrationController" class="org.convey.registration.controller.UserAdministration"/>

 <bean id="configurationLoader"
         class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader"/>
 <bean id="validator" class="org.springmodules.validation.bean.BeanValidator"
         p:configurationLoader-ref="configurationLoader"/>

</beans>

8. userRegistrationsuccessView.jsp 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
        <head><title>User Registration success Page.</title></head>
        <body>
               <b>user registration process success</b>

              <h2>username ${username}</h2>
              <h2>password ${password}</h2>
              <h2>email ${email}</h2>
        </body>
</html>


9. pom.xml file




    4.0.0
    SpringHibernate
    hibernate
    war
    1.0
    hibernate

    
        
            JBoss repository
            http://repository.jboss.com/maven2/
        

        
            maven2-repository.dev.java.net
            Java.net Repository for Maven
            http://download.java.net/maven/2/
            default
        

    


    
        UTF-8
        3.0.5.RELEASE
    

    
        

        
            org.springframework
            spring-web
            ${org.springframework.version}
        

        
            org.springframework
            spring-webmvc
            ${org.springframework.version}
        

        

        
            org.slf4j
            slf4j-log4j12
            1.5.6
        

        

        
        
            javax.servlet
            jstl
            1.1.2
        

        
            taglibs
            standard
            1.1.2
        
        

        
        
            org.springmodules
            spring-modules-validation
            0.9
        

        
        
            commons-lang
            commons-lang
            2.3
        

        
            commons-collections
            commons-collections
            3.1
        

    


    
        

            
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    1.6
                    1.6

                

            


            
            

                org.apache.maven.plugins
                maven-war-plugin
                2.0.2

                
                
                    src/main/webapps
                

            

        
        hibernate
    


you can access the project through the following link.


http://localhost:8080/hibername/userRegistration/register



you can download the full source code  for the project through the following link.

Download Source


In addition, the source code is available at the following GIT repository.

git@github.com:chathurangat/SpringModules-Annotation-based-Validation.git
 

once the source is downloaded, you will have to execute the  following command in the vi editor for building the project using maven.

maven clean install -DskipTests

once the project is build, copy the hibernate.war file (that is inside the target directory) to the webapps directory of your tomcat server.

regards
Chathuranga Tennakoon
chathuranga.t@gmail.com

Wednesday, September 21, 2011

Annotation based Mapping Vs XML ( .hbm.xml) based Mapping in Hibernate


There are two main ways to perform ORM (Object to Relational Mapping) in hibernate. Those can be summarized as follows.

  1. Annotation based Mapping
  1. XML based Mapping(using hbm.xml file)


today we are going to perform ORM using both of those approaches for the following table using the following POJO class (called Contact.java).

CREATE TABLE CONTACTS
(
    id              INT PRIMARY KEY AUTO_INCREMENT,
    firstname    VARCHAR(30),
    lastname    VARCHAR(30),
    telephone   VARCHAR(15),
    email         VARCHAR(30),
    created     TIMESTAMP DEFAULT NOW()
);


POJO Class


package sample.hibernate.chathuranga.classes;


public class Contact {

private Integer id;


private String firstname;


private String lastname;


private String email;


private String telephone;

public String getEmail() {
return email;
}

public String getTelephone() {
return telephone;
}

public void setEmail(String email) {
this.email = email;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

public String getFirstname() {
return firstname;
}

public String getLastname() {
return lastname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}
}







XML based Mapping(using hbm.xml file)

here the Object to Relational Mapping is done inside a xml file which has hbm.xml extension. This file is placed inside the resources directory of the project. You can see the below sample Contacts.hbm.xml file.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="sample.hibrernate.chathuranga.classes">

<class name="Contact" table="CONTACTS">

<id name="id" column="ID">
<generator class="native"/>
</id>

<property name="firstname" column="FIRSTNAME" />
<property name="lastname" column="LASTNAME" />
<property name="email" column="EMAIL" />
<property name="telephone" column="TELEPHONE" />

</class>

</hibernate-mapping> 


Annotation based Mapping

here the mapping will be done inside the data model (in the POJO classes) using the specific notations (known as annotations). The above POJO class with annotation based ORM mapping is as follows.


package sample.hibernate.chathuranga.classes;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "CONTACTS")
public class Contact {

@Id
@Column(name = "ID")
@GeneratedValue
private Integer id;

@Column(name = "FIRSTNAME")
private String firstname;

@Column(name = "LASTNAME")
private String lastname;

@Column(name = "EMAIL")
private String email;

@Column(name = "TELEPHONE")
private String telephone;

public String getEmail() {
return email;
}

public String getTelephone() {
return telephone;
}

public void setEmail(String email) {
this.email = email;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

public String getFirstname() {
return firstname;
}

public String getLastname() {
return lastname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}
}



Important:

it is required to add necessary lines to reflect your mapping option inside the hibernate.cfg.xml file. This file is placed inside the resources directory of the project.


--------------------------------------------------------------------------------------------------------
If you are using xml based mapping, then declare mapping resource as follows.

<mapping resource="sample/hibernate/chathuranga/classes/Contact.hbm.xml"/>

(here i have created a package called sample/hibernate/chathuranga/classes inside the resources directory and the Contact.hbm.xml file has been placed there)

--------------------------------------------------------------------------------------------------------
if you are using annotation based mapping, then declare the mapping class as follows.

<mapping class="sample.hibernate.chathuranga.classes.Contact"/>

Wednesday, September 7, 2011

How to add Maven compiler plugin in to your pom.xml file

<build>
<plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
       </plugins>
</build>

in configuration, you have to specify your JDK version.... (in my case it is JDK 1.6)

this plugin should be added inside to the <build> </build> section in your pom.xml file


Regards
Chathuranga Tennakoon


Thursday, August 11, 2011

Different ways to perform Sample URL handler Mapping in Spring


Normally the SimpleUrlHandlerMapping is done inside the xxx-servlet.xml file that is inside the WEB-INF directory of your Spring project. There are different ways to do this and two ways can be described as below.


Sample

Method 1

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/account/register.jsp=flowController
</value>
</property>
<property name="alwaysUseFullPath" value="true"/>
</bean>



Method 2

<bean id="sampleMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key ="/account/register.jsp">
flowController
</prop>
</props>
</property>
<property name="alwaysUseFullPath" value="true"/>
</bean>


flowController is an another bean id and that bean is refered whenever the relevant URL request comes.


Regards
Chathuranga Tennakoon

How to create web application project using maven

today i decided to post how to create new web application project using maven. the following command should be typed in your linux vi editor for creating new project with maven. In linux terminal, go inside your project directory where the project source files should be created.then invoke the following command in the VI editor to create new project.


mvn archetype:generate -DgroupId=org.convery.example -DartifactId=SpringEmailInGmail  -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0


the most importnat parameter can be described as belows.

-DgroupId this reffers to the Packaging path
-DartifactId this refes to the project id


once this command is executed, it will take few times to create new project. once the project is created you can see the newly created project structure as follows.

SpringEmailInGmail (as we have specified for the project name)
|------ pom.xml
|
|-------src
          |----main
                  |-----------resources
                  |
                  |-----------webapp
                                   |---------index.jsp
                             |
                                   |---------WEB-INF
                                                 |-----web.xml




hope this will helpful for you..

regards
Chathuranga Tennakoon
chathuranga.t@gmail.com