Showing posts with label Spring MVC. Show all posts
Showing posts with label Spring MVC. Show all posts

Wednesday, February 15, 2012

JasperReport with Spring MVC (fully working example with source code and explanation)

Today i am going to discuss how to integrate  jasper report with Spring MVC. i will be using following sample Spring MVC Application to show how the spring mvc and jasper report is integrated. you can download this application through following URL or GitHub repository.

https://github.com/chathurangat/spring-mvc-jpa-example

or

4shared URL

once you download the project, load it with your preferable development IDE. i have use Intelli J IDEA. the project structure is shown in the below screen shot.



the jasper report will be designed to display a list of Users who are already in the database(in User Table). this User table has been mapped to the User.java model that is available inside the org.convey.user.registration.model package. you can see the source code of the User.java model as follows.

User.java

package org.convey.user.registration.model;

import javax.persistence.*;
import java.util.Date;
import java.util.List;


@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private int id;

    @Column(name = "username" , nullable = false , unique = true)
    private String userName;

    @Column(name = "password" , nullable = false)
    private String passWord;

    @Column(name = "email" , nullable = false , unique = true)
    private String email;

    @Column(name = "confirmation_code",length = 20)
    private String confirmationCode;

    @Column(name = "first_name" , length = 50,nullable = false)
    private String firstName;

    @Column(name = "last_name" , length = 50)
    private String lastName;

    @Column(name = "register_date")
    private Date registeredDate;

    @Column(name = "activate_status")
    private boolean  activate;

    @Version
    private int version;

    @ManyToMany
    @JoinTable(name ="user_module",
            joinColumns = {@JoinColumn(name = "userID", referencedColumnName = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "moduleID", referencedColumnName ="module_id")})
    private List<Module> modules;


    public int getId() {
        return id;
    }

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

    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;
    }

    public String getConfirmationCode() {
        return confirmationCode;
    }

    public void setConfirmationCode(String confirmationCode) {
        this.confirmationCode = confirmationCode;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getRegisteredDate() {
        return registeredDate;
    }

    public void setRegisteredDate(Date registeredDate) {
        this.registeredDate = registeredDate;
    }

    public boolean isActivate() {
        return activate;
    }

    public void setActivate(boolean activate) {
        this.activate = activate;
    }


    public List<Module> getModules() {
        return modules;
    }

    public void setModules(List<Module> modules) {
        this.modules = modules;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

}//User




now it is the time to design the report using iReport. you can follow the below instructions to design your jasper report with iReport designer.

  • run the iReport tool. then File->New . then you will get the following set of available jasper report templates


  • In my case i have selected the Blank A4 report template. once you select the required report template, click Open this Template button to open the template.then you will get the following window.


then give a name for the report and select a location where the jrxml file should be saved.then click Next . after finishing all required operations you can see the selected template is loaded and ready o start the designing. please see the below.




if the palette is not automatically loaded in your designer, you can load it manually(window->palette)


you will see an another window called Report Inspector. you can add  the required fields for the report through this window. this can be done as follows.


right click on the Fields and select Add new Field Option.then you can see that newly added field is available under the Fields. you can change its attributes (name,type etc...) through the properties window. (Add up to four new fields)

Important:

when naming the fields, please make sure to name each field that is exactly same as the attribute name. In addition the data type (Field class) should also be same as the data type of identical attribute in the class. for more details, please see the below window. (we are going to design the report based on only the four attributes of the User class. therefore we need to create only four fields for the report). make sure to change the necessary properties of the newly added fields to reflect the below values.

attribute name(User class)     Field Name      Data Type(User class)     Field Class
 id                                              id                    int                                      Integer
 userName                                userName       String                                 String
 email                                        email               String                                 String
 firstName                                firstName        String                                 String


you can see that both attribute names and field names are identical. in addition there data types are also identical.now i assume that you have added new fields and changed their names and data types to meet above requirements. you can see all newly added fields as follows.



now you have loaded required components for your report design. now you can start  the design of your report. i will show you how to added newly created fields for your report.


drag and drop the newly added fields to the Detail 1 section of your report. please refer the below screen shot.



you can preview the design with the preview button.

now it is the time to start the jasper report integration with the spring mvc web application.suppose you have already downloaded the sample application given above for proceeding with this tutorial. you need to place the created jrxml file  in the class path. (in my case chathuranga-test-report.jrxml ).

 the jrxml file should be placed in the spring-mvc-jpa-jasper-report-example/src/main/resources location of the above downloaded project.

 then follow the instructions given below.

1. add the following maven dependencies to the pom.xml file.


<dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>3.7.6</version>
            <type>jar</type>
            <scope>compile</scope>           
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.6</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>

        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>2.1</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>1.7.0</version>
        </dependency> 
 
 
2. add the following Report controller to your controller package.
(available in spring-mvc-jpa-jasper-report-example/src/main/java/org/convey/user/registration/controller )

ReportController.java

package org.convey.user.registration.controller;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.convey.user.registration.dao.UserDao;
import org.convey.user.registration.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;



@Controller
@RequestMapping("/report/")
public class ReportController {


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

    @Autowired
    UserDao userDao;

    @RequestMapping(method = RequestMethod.GET , value = "pdf")
    public ModelAndView generatePdfReport(ModelAndView modelAndView){

        logger.debug("--------------generate PDF report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //pdfReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("pdfReport", parameterMap);

        return modelAndView;

    }//generatePdfReport



    @RequestMapping(method = RequestMethod.GET , value = "xls")
    public ModelAndView generateXlsReport(ModelAndView modelAndView){

        logger.debug("--------------generate XLS report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //xlsReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("xlsReport", parameterMap);

        return modelAndView;

    }//generatePdfReport


    @RequestMapping(method = RequestMethod.GET , value = "csv")
    public ModelAndView generateCsvReport(ModelAndView modelAndView){

        logger.debug("--------------generate CSV report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //xlsReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("csvReport", parameterMap);

        return modelAndView;

    }//generatePdfReport



    @RequestMapping(method = RequestMethod.GET , value = "html")
    public ModelAndView generateHtmlReport(ModelAndView modelAndView){

        logger.debug("--------------generate HTML report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //xlsReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("htmlReport", parameterMap);

        return modelAndView;

    }//generatePdfReport


}//ReportController





3. add the following jasper-view.xml file to the same directory where the applicationContext.xml file contains. (in this example, it is should be placed under the spring-mvc-jpa-jasper-report-example/src/main/webapp/WEB-INF/spring/app directory.

<?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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
  http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/util 
  http://www.springframework.org/schema/util/spring-util-3.0.xsd">

     <!--here all the url value should contains the valid path for the jrxml file-->
    
    <bean id="pdfReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource" />


    <bean id="xlsReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsXlsView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource" />


    <bean id="htmlReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource" />


    <bean id="csvReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsCsvView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource"/>


</beans>

here all the url properties should contains the valid reference for a jrxml file that should be used as the report template.


4. then make the below XmlViewResolver bean declaration in your  applicationContext.xml file

    <beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
        <beans:property name="location" value="/WEB-INF/spring/app/jasper-views.xml"/>
        <beans:property name="order" value="0"/>
    </beans:bean>  

the value of location property should contains the reference for the xml file where the jasper view declarations are available.(in this case jasper-view.xml)


In addition, import the jasper-view.xml file to your applicationContext.xml file by placing the below import statement in your applicationContext.xml 


<beans:import resource="jasper-views.xml"/> 

Please make sure to change your database properties in the spring-mvc-jpa-jasper-report-example/src/main/resources/db.properties file.

then build your project with maven and deploy it in the tomcat server. then use following urls for getting the report you need.

PDF Report
 http://localhost:8080/common-user-registration/spring/report/pdf

XLS Report
 http://localhost:8080/common-user-registration/spring/report/xls

CSV Report
 http://localhost:8080/common-user-registration/spring/report/csv

HTML Report
 http://localhost:8080/common-user-registration/spring/report/html


you can download the fully example of this application through the  following git repository .

https://github.com/chathurangat/spring-mvc-jpa-jasper-report-example

Hope this will helpful for you !!!

Regards
Chathuranga Tennakoon
chathuranga.t@gmail.com

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

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

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

Tuesday, December 7, 2010

Spring MVC Annotation based Helloworld Example with LOG4J logging support


Today we will look at how to write Spring MVC hello world application using Spring Annotations. This tutorial will be completely different from other available tutorials in the web because, I have tried to show how to externalize property values from the BeanFactory definition and how to place them in a separate standard files called properties files. In addition, I will be using apache log4j framework to make the required logs for this application. Therefore you will be having the chance to investigate more on these technologies throughout this article. The overall directory and the file structure of the project is as follows.


I have used the following technologies and frameworks to make this simple example.

Apache Maven as the building tool
Apache Log4J as the logging framework
Spring MVC framework
Apache Tomcat for running this Application
Intelli J IDEA as the Development IDE


you can see the content of the each file as below.

 
pom.xml 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


    <modelVersion>4.0.0</modelVersion>
    <groupId>SpringMVC</groupId>
    <artifactId>SpringMVC</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>SpringMVC</name>

    <repositories>
        <repository>
            <id>JBoss repository</id>
            <url>http://repository.jboss.com/maven2/</url>
        </repository>

    </repositories>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
    </properties>

    <dependencies>
        <!-- spring dependency starts-->
        <!-- Spring Framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Spring MVC Framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <!-- spring dependency ends-->

        <!-- JSTL Dependencies start -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>

        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- JSTL Dependencies ends -->


        <!--Logging Dependencies Starts-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <!--Logging Dependencies Ends-->

    </dependencies>


    <build>
        <plugins>

            <!-- Maven compiler plugin that says to use JDK 1.6 version for compiling the project -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>

                </configuration>

            </plugin>


            <!-- Maven WAR  plugin -->
            <plugin>

                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.0.2</version>

                <configuration>
                    <warSourceDirectory>src/main/webapps</warSourceDirectory>
                </configuration>

            </plugin>
        </plugins>
        <!-- Final project build name -->
        <finalName>SpringMVC</finalName>
    </build>

</project>


HelloWorldControlller.java

this is the main(core) controller of this simple web application. You can see that we have used annotations for request mappings and other required configurations. As you can see the developer.name and developer.email properties have been defined in a external property file and they are accessed in the controller using the special annotations dedicated for that. The property values will be injected to the relevant variables using the @Value annotation.


package org.convey.example.Controller;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
Author: Chathuranga Tennakoon
Email: chathuranga.t@gmail.com

 */

@Controller
@RequestMapping("/HelloWorld")
public class HelloWorldController {


    private static final Logger logger = Logger.getLogger(HelloWorldController.class);

    @Value("${developer.name}")
    private String developerName;

    @Value("${developer.email}")
    private String developerEmail;

    @RequestMapping("/hello")
    public ModelAndView helloWorldMethod(){

        logger.debug(" invoking the helloWorldMethod method ");

        ModelAndView model=new ModelAndView("SayHelloView");

        model.addObject("developer_name",developerName);
        model.addObject("developer_email",developerEmail);


        return model;

    }//helloWorldMethod

}//helloWorldController



messages.properties

this file is located inside the resources/properties/ directory. The content of this file is as follows.

#Sample Screen Message values
developer.name=chathuranga tennakoon
developer.email=chathuranga.t@gmail.com

 

 
web.xml

you will see that the Spring MVC Dispatcher servlet is mapped and configured inside the web.xml file.
In additon, the log4j configuration is also done inside the web.xml file.(furthermore you can define and configure Filters and Listeners inside the web.xml file if required.)

<?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>Spring3-HelloWorld-Example</display-name>
<!-- LOG4J Configuration -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/resources/log4j.xml</param-value>
</context-param>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Spring MVC Dispatcher Servlet Mapping start -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring MVC Dispatcher Servlet Mapping ends -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>


hello-servlet.xml

this represents the Dispatcher servlet of your web application. As you can see in the web.xml , you have named the dispater servlet as hello. Therefore your dispatcher servlet will be named as hello-servlet.xml. The beans that are declared in this servlet will be initiated when the Dispatcher servlet loading time. All the declared beans will be created in the Spring bean container.

<?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"
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">

<import resource="applicationContext.xml"/>

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

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

<bean id="HelloController" class="org.convey.example.Controller.HelloWorldController"/>

</beans>

SayHelloView.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html>
<body>
<h1>Spring MVC Hello World Annotation Example</h1>

<!-- JSTL Tag libraries are required for the EL(Expression Language) -->
<h5>developed by : ${developer_name}</h5>
<h5>Email : ${developer_email}</h5>

</body>
</html>



applicationContext.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"
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">

<context:component-scan base-package="org.convey.example.Controller" />
<!-- actual view is resolved with the prefix + resolverName + suffix . if the resolverName is sayHelloView, then the actual resolved view will be /WEB-INF/view/sayHelloView.jsp ( /WEB-INF/view/ + sayHelloView + .jsp ) -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >

<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>

<!-- the below bean is configured to define external property file for defining property values for the application -->
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- messages have been defined inside the resources/properties/messages.properties file -->
<value>classpath:properties/messages.properties</value>
</list>
</property>
</bean>

</beans>


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>


How to run the project?

After placing the all required files in the relevant locations, you can use maven building tool to build your application. The following command can be used in your terminal to build the web application.

mvn clean install

once the project is build, you will see the war file (SpringMVC.war) inside the directory called target in your project source location. You can deploy the SpringMVC.war file in the tomcat server and see the output. It will display as below.

Browse the following URL to see the output.

http://localhost:8080/SpringMVC/HelloWorld/hello




 
Please remember to check the logs directory of your tomcat server installation and see whether there is a file called sample.log. This file should contains the log records which were generated during the execution of this web application. In additon, check whether the console appenders. In order to check the console appenders, you can use the following command in your terminal.(i assume that you are using a linux operating system.)

tail -f logs/catalina.out



regards
Chathuranga Tennakoon