Friday, December 2, 2011

POJO and JavaBean

Pojo stands for Plain Old Java Objects. "POJO" is mainly used to denote a Java object which does not follow any of the major Java object models, conventions, or frameworks. The term continues the pattern of older terms for technologies that do not use fancy new features. The equivalent to POJO on the .NET framework is Plain Old CLR Object

Pojo contains the business logic for extensions.

An example of POJO:


package springapp.domain;

import java.io.Serializable;

public class Product implements Serializable {

    private String description;
    private Double price;
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public Double getPrice() {
        return price;
    }
    
    public void setPrice(Double price) {
        this.price = price;
    }
    
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Description: " + description + ";");
        buffer.append("Price: " + price);
        return buffer.toString();
    }
}
 
JavaBean 

A JavaBean is a POJO that is serializable, has a no-argument constructor, and 
allows access to properties using getter and setter methods that follow a simple 
naming convention. Because of this convention, simple declarative references can 
be made to the properties of arbitraryJavaBeans. 
Code using such a declarative reference does not have to know anything about the 
type of the bean, and the bean can be used with many frameworks without these 
frameworks having to know the exact type of the bean.
 
e.g:
 
public class MyBean implements java.io.serializable {
 
    private String someProperty;
 
    public String getSomeProperty() {
         return someProperty;
    }
 
    public void setSomeProperty(String someProperty) {
        this.someProperty = someProperty;
    }
} 

Advantages of JavaBean

  • A Bean obtains all of the benefits of Java's "write once, run anywhere" paradigm.
  • The properties, events, and methods of a Bean that are exposed to another application can be controlled.
  • Auxiliary software can be provided to help configure a Bean.
  • The configuration settings of a Bean can be saved in a persistent storage and can be restored at a later time.
  • A Bean may register to receive events from other objects and can generate events that are sent to other objects.
Java Bean Conventions:
 
In order to function as a JavaBean class, an object class must obey certain conventions about method naming, construction, and behaviour. These conventions make it possible to have tools that can use, reuse, replace, and connect JavaBeans.
The required conventions are as follows:
  • The class must have a public default constructor (no-argument). This allows easy instantiation within editing and activation frameworks.
  • The class properties must be accessible using get, set, is (used for boolean properties instead of get) and other methods (so-called accessor methods and mutator methods), following a standard naming convention. This allows easy automated inspection and updating of bean state within frameworks, many of which include custom editors for various types of properties. Setters must receive only one argument.
  • The class should be serializable. It allows applications and frameworks to reliably save, store, and restore the bean's state in a fashion independent of the VM and of the platform.
 
DAO (Data Access Object Pattern)


What is the DAO Pattern?

We will (eventually) migrate all of the code that is used to access/manipulate the database, configuration files, the RRD files, or other externally data like reports or graphs to use the Data Access Object (DAO) Design Pattern. This pattern encapsulates access and manipulation of external data sources such as databases, config files and others. The DAO pattern creates the flexibility to change the format or location of data without needing to go through and rewrite the entire application.


The DAO Pattern defines five 'roles' or collaborators in the working of the pattern. These roles are as follows:
The Client
This role represents the 'Business Objects' or objects that need to access or modify the data.
The DAO Interace
This role is the operations (i.e. quieres and updates) that Data Access Objects define. These operations might include findById(nodeId) or getOpenOutagesForService(Service)
The Data Transfer Object
This role is the object that represents the data retrieved from the data source. An example object would be a Node or an Interface for a Database DAO or a User or Group for an XML based DAO.
The DAO Implementation
This provides the actual implementation of the DAO Interface. It is written for the particular data source the contains the data. These might include JDBCNodeDAO or CastorUserDAO, for node data stored in a database accessed via JDBC and for user data stored in an XML file accessed via castor respectively.
The Data Source
This represents the external location of the data abstracted by the DAO. This is can be a relational database, XML file, proprietary file format, web service or other external data location.

                                                                   Data Access Object sequence diagram

The Strategy

The approach we will take migrate OpenNMS to use the DAO Pattern is as follows:
  1. Define Data Transfer objects representing the data in a single row of each table defined by an OpenNMS's postgresql database.
  2. Create empty DAO interfaces for each table that will eventually have methods used to access the data from the table.
  3. Create a stub implementation extends Spring's HibernateSupport class that will use Hibernate to query the data and implement the DAO operations
  4. Use XDoclet on the Data Transfer object to define the Hibernate object to relational mapping and generate the hibernate configuration files.
  5. Setup a Spring application context file that sets up all of the DAO objects as well as the Hibernate session needed to correctly retrieve the data.
  6. Go through the code looking for database access code. In any location where database access is made, place an appropriate call to locate the DAO (or even better inject the DAO)
  7. Next define a DAO operation that provides the data
  8. Implement the operation in the DAO Implementation using Hibernate
  9. Once this is done we will enhance this strategy to discuss using the DAO Pattern for XML and RRD Files and any other places where it would make sense.
Notes: Any code that exists solely to cache database data should be removed. It this is necessary for acceptable performance it should be done inside of the DAO rather than external to it. Examples of this would be places in the code where the serviceID to serviceName maps are maintained to avoid an additional DB query.


Advantages of DAO:

  • Enables Transparency
    Business objects can use the data source without knowing the specific details of the data source's implementation. Access is transparent because the implementation details are hidden inside the DAO.
  • Enables Easier Migration
    A layer of DAOs makes it easier for an application to migrate to a different database implementation. The business objects have no knowledge of the underlying data implementation. Thus, the migration involves changes only to the DAO layer. Further, if employing a factory strategy, it is possible to provide a concrete factory implementation for each underlying storage implementation. In this case, migrating to a different storage implementation means providing a new factory implementation to the application.
  • Reduces Code Complexity in Business ObjectsBecause the DAOs manage all the data access complexities, it simplifies the code in the business objects and other data clients that use the DAOs. All implementation-related code (such as SQL statements) is contained in the DAO and not in the business object. This improves code readability and development productivity.
  • Centralizes All Data Access into a Separate Layer
    Because all data access operations are now delegated to the DAOs, the separate data access layer can be viewed as the layer that can isolate the rest of the application from the data access implementation. This centralization makes the application easier to maintain and manage.
  • Not Useful for Container-Managed Persistence
    Because the EJB container manages entity beans with container-managed persistence (CMP), the container automatically services all persistent storage access. Applications using container-managed entity beans do not need a DAO layer, since the application server transparently provides this functionality. However, DAOs are still useful when a combination of CMP (for entity beans) and BMP (for session beans, servlets) is required.
  • Adds Extra Layer
    The DAOs create an additional layer of objects between the data client and the data source that need to be designed and implemented to leverage the benefits of this pattern. But the benefit realized by choosing this approach pays off for the additional effort.
  • Needs Class Hierarchy Design
    When using a factory strategy, the hierarchy of concrete factories and the hierarchy of concrete products produced by the factories need to be designed and implemented. This additional effort needs to be considered if there is sufficient justification warranting such flexibility. This increases the complexity of the design. However, you can choose to implement the factory strategy starting with the Factory Method pattern first, and then move towards the Abstract Factory if necessary.

Why Hibernate

Hibernate was selected because it provides efficient object to relation mapping technology. It enables us to efficiently represent objects in a relation database that allows to put object methods where they belong and even provides for appropriate inheritance relationships. As the code improves Hibernate will make for an easier more extendible implementation.

Why Spring

Spring has a sophisticated implementation for dealing with transactions, exceptions, and database sessions/connections. It enables us to declaratively define transactions via configuration file as well as a mechanism for 'wiring' up beans that makes for code this is both testable and easy to use. Addidtionally Spring's 'proxy' features will enable us to distribute the different pieces of OpenNMS readily.

Wednesday, October 5, 2011


Installation and set up

Eclipse,Tomcat,ANT, Spring Framework Guide
                                                 Author: Anup Niroula

1. Installing and configuring Eclipse IDE for Web Development

To download eclipse in ubuntu: sudo apt-get install eclipse

In Linux, we need to install WTP plugins for JEE to create web applications.

# how to install Web Tools Platform(WTP) plugins in eclise ..?

1. Run the Eclipse IDE
2. Go to Help Menu-->Install new software
3. Give this url  on 'work with' http://download.eclipse.org/releases/galileo/ and click 'Add' to download Java EE plugins from the repository
Note: There are two projects of eclipse: Galileo and helios. The one we are using is Galileo.
So, do not install plugins from the helios repository. For helios repository the url is:
(http://download.eclipse.org/webtools/updates)

4. Click next and select WTP packages to install
5. After you are done restart eclipse IDE
6. Change the eclipse perspective
     click on Window--> Open Perspective --> JEE

-end of file-
-------------------------------------------------------------------------------------------------------------------
 2.  Installing and configuring Apache Tomcat Server: 7.0.22

Pre-requisites:
you must have java 6 installed.

1. Download Apache tomcat 7.0.22 or higher version from http://tomcat.apache.org/download-70.cgi?Preferred=http%3A%2F%2Fapache.mirrors.hoobly.com%2F

2. Extract it and place it under /usr/local/tomcat7

3. For autostart create following script in /etc/init.d  

[sudo vi /etc/init.d/tomcat7]

paste these following lines
***********************************************
# Tomcat auto-start
#
# description: Auto-starts tomcat 7
# processname: tomcat7
# pidfile: /var/run/tomcat.pid

export JAVA_HOME=/usr/lib/jvm/java-6-sun

case $1 in
start)
        sh /usr/local/tomcat7/bin/startup.sh
        ;;
stop)  
        sh /usr/local/tomcat7/bin/shutdown.sh
        ;;
restart)
        sh /usr/local/tomcat7/bin/shutdown.sh
        sh /usr/local/tomcat7/bin/startup.sh
        ;;
esac   
exit 0
************************************************

4. Save the file and set executable permissions
[sudo chmod 755 /etc/init.d/tomcat7]

5. Link the startup script to startup folders
[sudo ln -s /etc/init.d/tomcat7 /etc/rc1.d/K99tomcat]
[sudo ln -s /etc/init.d/tomcat7 /etc/rc2.d/S99tomcat]

6. Finally start the tomcat server
sudo /etc/init.d/tomcat7 start

7. Test the setup in browser
Open URL : http://localhost:8080/ -- you should be able to see the tomcat welcome page
----------------------------------------------------------------------------------------------------------------------------------------------------
3. Configuration for Running Tomcat from eclipse:

To work it around, you need to add the tomcat-juli.jar to the run configuration class path.

Here are the steps how to do it:
1. In Eclipse, Open the "Server" tab.
2. Double click on the "Tomcat7" entry to see the configuration.
3. Then click on the "Open launch configuration" link in the "General information" block.
4. In the dialog, select the "Classpath" tab.
5. Click the "Add external jar" button.
6. Select the file "/usr/local/tomcat7/bin/tomcat-juli.jar" (select from where your tomcat is installed)
7. Close the dialog.
8. Start tomcat 7 from Eclipse.
 -----------------------------------------------------------------------------------------------------------------------
4. Installing Ant Build Tool:

1. download the latest version of Ant from:
                    http://ant.apache.org/bindownload.cgi

2. place it under:
        /usr/local/

3. set the environment variable for ant
                    sudo gedit /etc/bash.bashrc

Add the following lines to bash.bashrc file:
                    export ANT_HOME=/usr/local/ant
                    set path=$path $ANT_HOME/bin


4. After setting up tomcat with eclipse and completed writing the web application:
     open Terminal: ant -version (just checking if the installation is correct)
 ---------------------------------------------------------------------------------------------------------------------


5. Installing Spring Framework:

1) Download spring framework 3.0.6 from:

    http://www.springsource.org/download

2) extract the zip file and keep the extracted file in /usr/local/

3) Inside extracted spring folder, there are four files:
        i. dist
        ii. docs
        iii. projects
        iv. src

4) To configure spring framework:
 - simply add all jar files in the 'dist' folder to the the library (in eclipse) using   build path
   - Also add common-logging.jar file to the library (where is this jar file?-- spring framework 3.1.0.M2 -->projects-->spring-build-->lib-->ivy)
   - Finally copy all the jar files in 'dist'+ common-logging.jar file and paste it in lib folder in eclipse ( where? in eclipse--war -->WEB-INF-->lib)

(Remember: one more jar file for Junit test which must be added to build path is: "junit-4.10.jar" , you can add it later)

Tuesday, August 2, 2011

Web Application environment set up

----------------------------------------------------------------------------------------

Development environment:  

Operating System: Ubuntu/Linux

IDE : Eclipse 3.5.2

Framework: Spring Framework 3.1.0.M2

Server: Apache Tomcat 7.0.22

Build Tool: Ant 1.8.2

------------------------------------------------------------------------------------------

Basic Application and Environment Setup

1.1. Create the project directory structure

We are going to need a place to keep all the source and other files we will be creating, so let's create a directory named 'springapp'. The decision as to where you create this directory is totally up to you; we created ours in a 'Projects' directory that we already had in our 'home' directory so the complete path to our project directory is now '$HOME/workspace/springapp'. Inside this directory we create a sub-directory named 'src' to hold all the Java source files that we are going to create. Then we create another sub-directory that we name 'war'. This directory will hold everything that should go into the WAR file that we will use to package and deploy our application. All source files other than Java source, like JSPs and configuration files, belong in the 'war' directory.


The project directory structure

1.2. Create 'index.jsp'

Since we are creating a web application, let's start by creating a very simple JSP page named 'index.jsp' in the 'war' directory. The 'index.jsp' is the entry point for our application.
'springapp/war/index.jsp':

*************************************************************************
<html>
  <head><title>Example :: Spring Application</title></head>
  <body>
    <h1>Example - Spring Application</h1>
    <p>This is my test.</p>
  </body>
</html>
************************************************************************************
 
Just to have a complete web application, let's create a 'WEB-INF' directory inside the 'war' directory and place a 'web.xml' file in this new directory.
'springapp/war/WEB-INF/web.xml':
**************************************************************************
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

  <welcome-file-list>
    <welcome-file>
      index.jsp
    </welcome-file>
  </welcome-file-list>

</web-app>
************************************************************************************* 

1.3. Deploy the application to Tomcat

Let's now write the Ant build script that we are going to use throughout the tutorial. This Ant build script will contain targets for compiling, building and deploying the application. A separate build script will be used for application server specific targets, such as targets for controlling the application under Tomcat.
'springapp/build.xml':
****************************************************************************
<?xml version="1.0"?>

<project name="springapp" basedir="." default="usage">
    <property file="build.properties"/>

    <property name="src.dir" value="src"/>
    <property name="web.dir" value="war"/>
    <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
    <property name="name" value="springapp"/>

    <path id="master-classpath">
        <fileset dir="${web.dir}/WEB-INF/lib">
            <include name="*.jar"/>
        </fileset>
        <!-- We need the servlet API classes: -->
        <!--  * for Tomcat 5/6 use servlet-api.jar -->
        <!--  * for other app servers - check the docs -->
        <fileset dir="${appserver.lib}">
            <include name="servlet*.jar"/>
        </fileset>
        <pathelement path="${build.dir}"/>
    </path>

    <target name="usage">
        <echo message=""/>
        <echo message="${name} build file"/>
        <echo message="-----------------------------------"/>
        <echo message=""/>
        <echo message="Available targets are:"/>
        <echo message=""/>
        <echo message="build     --> Build the application"/>
        <echo message="deploy    --> Deploy application as directory"/>
        <echo message="deploywar --> Deploy application as a WAR file"/>
        <echo message="install   --> Install application in Tomcat"/>
        <echo message="reload    --> Reload application in Tomcat"/>
        <echo message="start     --> Start Tomcat application"/>
        <echo message="stop      --> Stop Tomcat application"/>
        <echo message="list      --> List Tomcat applications"/>
        <echo message=""/>
    </target>

    <target name="build" description="Compile main source tree java files">
        <mkdir dir="${build.dir}"/>
        <javac destdir="${build.dir}" source="1.5" target="1.5" debug="true"
               deprecation="false" optimize="false" failonerror="true">
            <src path="${src.dir}"/>
            <classpath refid="master-classpath"/>
        </javac>
    </target>

    <target name="deploy" depends="build" description="Deploy application">
        <copy todir="${deploy.path}/${name}" preservelastmodified="true">
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
            </fileset>
        </copy>
    </target>

    <target name="deploywar" depends="build" description="Deploy application as a WAR file">
        <war destfile="${name}.war"
             webxml="${web.dir}/WEB-INF/web.xml">
            <fileset dir="${web.dir}">
                <include name="**/*.*"/>
            </fileset>
        </war>
        <copy todir="${deploy.path}" preservelastmodified="true">
            <fileset dir=".">
                <include name="*.war"/>
            </fileset>
        </copy>
    </target>
    

    <path id="catalina-ant-classpath">
        <!-- We need the Catalina jars for Tomcat -->
        <!--  * for other app servers - check the docs -->
        <fileset dir="${appserver.lib}">
            <include name="catalina-ant.jar"/>
        </fileset>
    </path>

    <taskdef name="install" classname="org.apache.catalina.ant.DeployTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="list" classname="org.apache.catalina.ant.ListTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="start" classname="org.apache.catalina.ant.StartTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>
    <taskdef name="stop" classname="org.apache.catalina.ant.StopTask">
        <classpath refid="catalina-ant-classpath"/>
    </taskdef>

    <target name="install" description="Install application in Tomcat">
        <install url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"
                 war="${name}"/>
    </target>

    <target name="reload" description="Reload application in Tomcat">
        <reload url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="start" description="Start Tomcat application">
        <start url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="stop" description="Stop Tomcat application">
        <stop url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"
                 path="/${name}"/>
    </target>

    <target name="list" description="List Tomcat applications">
        <list url="${tomcat.manager.url}"
                 username="${tomcat.manager.username}"
                 password="${tomcat.manager.password}"/>
    </target>

<!-- End Tomcat tasks -->

</project>
*********************************************************************************
If you are using an IDE, you may find a number of errors reported by the IDE in the 'build.xml' such as the Tomcat targets. You can ignore these. The file listing above is correct.
The above Ant build script now contains all the targets that we are going to need to make our development efforts easier. You can just copy the above build file text and paste it into a new file called 'build.xml' in the root of your development directory tree. We also need a 'build.properties' file that you should customize to match your server installation. This file belongs in the same directory as the 'build.xml' file.
'springapp/build.properties':
# Ant properties for building the springapp

appserver.home=/usr/local/tomcat7
# for Tomcat 5 use $appserver.home}/server/lib
# for Tomcat 6 use $appserver.home}/lib
appserver.lib=${appserver.home}/lib

deploy.path=${appserver.home}/webapps

tomcat.manager.url=http://localhost:8080/manager
tomcat.manager.username=tomcat
tomcat.manager.password=tomcat


 
Now we run Ant to make sure that everything is working okay. You must have your current directory set to the 'springapp' directory.
Open up a command shell (or prompt) and execute 'ant' .
$ ant -f build.xml
Buildfile: build.xml

usage:
     [echo] 
     [echo] springapp build file
     [echo] -----------------------------------
     [echo] 
     [echo] Available targets are:
     [echo] 
     [echo] build     --> Build the application
     [echo] deploy    --> Deploy application as directory
     [echo] deploywar --> Deploy application as a WAR file
     [echo] install   --> Install application in Tomcat
     [echo] reload    --> Reload application in Tomcat
     [echo] start     --> Start Tomcat application
     [echo] stop      --> Stop Tomcat application
     [echo] list      --> List Tomcat applications
     [echo] 

BUILD SUCCESSFUL
Total time: 2 seconds
The last thing we need to do here is to build and deploy the application. Just run Ant and specify 'deploy' or 'deploywar' as the target.
$ ant deploy
Buildfile: build.xml

build:
    [mkdir] Created dir: /Users/trisberg/Projects/springapp/war/WEB-INF/classes

deploy:
     [copy] Copying 2 files to /Users/trisberg/apache-tomcat-5.5.17/webapps/springapp

BUILD SUCCESSFUL
Total time: 4 seconds

1.4. Check the application works

You can now open up a browser and navigate to the starting page of our application at the following URL: http://localhost:8080/springapp/index.jsp.

The application's starting page

1.5. Download the Spring Framework

Please look above post on how to download and install Spring Framework

1.6. Modify 'web.xml' in the 'WEB-INF' directory

Go to the 'springapp/war/WEB-INF' directory. Modify the minimal 'web.xml' file that we created earlier. We will define a DispatcherServlet (also known as a 'Front Controller' (Crupi et al)). It is going to control where all our requests are routed based on information we will enter at a later point. This servlet definition also has an attendant <servlet-mapping/> entry that maps to the URL patterns that we will be using. We have decided to let any URL with an '.htm' extension be routed to the 'springapp' servlet (the DispatcherServlet).
'springapp/war/WEB-INF/web.xml':
*****************
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

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

  <servlet-mapping>
    <servlet-name>springapp</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>
      index.jsp
    </welcome-file>
  </welcome-file-list>

</web-app>
************************ 
Next, create a file called 'springapp-servlet.xml' in the 'springapp/war/WEB-INF' directory. This file contains the bean definitions (plain old Java objects) used by the DispatcherServlet. It is the WebApplicationContext where all web-related components go. The name of this file is determined by the value of the <servlet-name/> element from the 'web.xml', with '-servlet' appended to it (hence 'springapp-servlet.xml'). This is the standard naming convention used with Spring's Web MVC framework. Now, add a bean entry named '/hello.htm' and specify the class as springapp.web.HelloController. This defines the controller that our application will be using to service a request with the corresponding URL mapping of '/hello.htm'. The Spring Web MVC framework uses an implementation class of the interface called HandlerMapping to define the mapping between a request URL and the object that is going to handle that request (the handler). Unlike the DispatcherServlet, the HelloController is responsible for handling a request for a particular page of the website and is also known as a 'Page Controller' (Fowler). The default HandlerMapping that the DispatcherServlet uses is the BeanNameUrlHandlerMapping; this class will use the bean name to map to the URL in the request so that the DispatcherServlet knows which controller must be invoked for handling different URLs.
'springapp/war/WEB-INF/springapp-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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

  <!-- the application context definition for the springapp DispatcherServlet -->

  <bean name="/hello.htm" class="springapp.web.HelloController"/>

</beans>

1.7. Copy libraries to 'WEB-INF/lib'

First create a 'lib' directory in the 'war/WEB-INF' directory. Then, from the Spring distribution, copy all jar files from spring-framework-3.1.0/dist and spring-webmvc.jar to the new 'war/WEB-INF/lib' directory. Also, copy commons-logging.jar (from spring framework 3.1.0.M2 -->projects-->spring-build-->lib-->ivy) to the 'war/WEB-INF/lib' directory. These jars will be deployed to the server and they are also used during the build process.

1.8. Create the Controller

Create your Controller class – we are naming it HelloController, and it is defined in the 'springapp.web' package. First we create the package directories and then we create the 'HelloController.java' file and place it in the 'src/springapp/web' directory.
'springapp/src/springapp/web/HelloController.java':
package springapp.web;

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;

public class HelloController implements Controller {

    protected final Log logger = LogFactory.getLog(getClass());

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        logger.info("Returning hello view");

        return new ModelAndView("hello.jsp");
    }

}
This is a very basic Controller implementation. We will be expanding this later on as well as extending some of the base controller implementations provided by Spring. In Spring Web MVC, the Controller handles the request and returns a ModelAndView - in this case, one named 'hello.jsp' which is also the name of the JSP file we will create next. The model that this class returns is actually resolved via a ViewResolver. Since we have not explicitly defined a ViewResolver, we are going to be given a default one by Spring that simply forwards to a URL matching the name of the view specified. We will modify this later on. We have also specified a logger so we can verify that we actually got into the handler. Using Tomcat, these log messages should show up in the 'catalina.out' log file which can be found in the '${appserver.home}/log' directory of your Tomcat installation.
If you are using an IDE, you will want to configure your project's build path by adding the jars from the 'lib' directory. You will also want to add servlet-api.jar from your servlet container's 'lib' directory ('${appserver.lib}'). Adding these to your build path should successfully resolve all the import statements in the 'HelloController.java' file.

1.9. Write a test for the Controller

Testing is a vital part of software development. It is also a core practice in Agile development. We have found that the best time to write tests is during development, not after, so even though our controller doesn't contain complex logic, we're going to write a test. This will allow us to make changes to it in the future with confidence. Let's create a new directory under 'springapp' called 'test'. This is where all our tests will go in a package structure that will mirror the source tree in 'springapp/src'.
Create a test class called 'HelloControllerTests' and make it extend JUnit's test class TestCase. It is a unit test that verifies the view name returned by handleRequest() matches the name of the view we expect: 'hello.jsp'.
'springapp/test/springapp/web/HelloControllerTests.java':
package springapp.web;

import org.springframework.web.servlet.ModelAndView;

import springapp.web.HelloController;

import junit.framework.TestCase;

public class HelloControllerTests extends TestCase {

    public void testHandleRequestView() throws Exception{		
        HelloController controller = new HelloController();
        ModelAndView modelAndView = controller.handleRequest(null, null);		
        assertEquals("hello.jsp", modelAndView.getViewName());
    }
}
To run the test (and all the tests we're going to write), we need to add an Ant test task to our build script 'build.xml'. First, download Junit-4.1.0.jar from http://sourceforge.net/projects/junit/files/junit/3.4/' to 'war/WEB-INF/lib'. Instead of creating a single task for compiling the tests and then running them, let's break them down into two distinct tasks: 'buildtests' and 'tests' which depends on 'buildtests'.
If you are using an IDE, you may want to run your tests within your IDE. Configure your project's build path by adding the junit-4.1.0.jar to it.'springapp/build.xml':
    <property name="test.dir" value="test"/>
        
    <target name="buildtests" description="Compile test tree java files">
        <mkdir dir="${build.dir}"/>
        <javac destdir="${build.dir}" source="1.5" target="1.5" debug="true"
            deprecation="false" optimize="false" failonerror="true">
            <src path="${test.dir}"/>
            <classpath refid="master-classpath"/>
        </javac>
    </target>
    
    <target name="tests" depends="build, buildtests" description="Run tests">
        <junit printsummary="on"
            fork="false"
            haltonfailure="false"
            failureproperty="tests.failed"
            showoutput="true">
            <classpath refid="master-classpath"/>
            <formatter type="brief" usefile="false"/>
            
            <batchtest>
                <fileset dir="${build.dir}">
                    <include name="**/*Tests.*"/>
                </fileset>
            </batchtest>
            
        </junit>
        
        <fail if="tests.failed">
            tests.failed=${tests.failed}
            ***********************************************************
            ***********************************************************
            ****  One or more tests failed!  Check the output ...  ****
            ***********************************************************
            ***********************************************************
        </fail>
    </target>
Now run the Ant 'tests' task and the test should pass.
$ ant tests
Buildfile: build.xml

build:

buildtests:
    [javac] Compiling 1 source file to /Users/Shared/Projects/springapp/war/WEB-INF/classes

tests:
    [junit] Running springapp.web.HelloWorldControllerTests
    [junit] Oct 30, 2007 11:31:43 PM springapp.web.HelloController handleRequest
    [junit] INFO: Returning hello view
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.03 sec
    [junit] Testsuite: springapp.web.HelloWorldControllerTests
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.03 sec

    [junit] ------------- Standard Error -----------------
    [junit] Oct 30, 2007 11:31:43 PM springapp.web.HelloController handleRequest
    [junit] INFO: Returning hello view
    [junit] ------------- ---------------- ---------------

BUILD SUCCESSFUL
Total time: 2 seconds
    
Another of the best practices of Agile development is Continuous Integration. It's a good idea to ensure your tests are run with every build (ideally as automated project builds) so that you know your application logic is behaving as expected as the code evolves.

1.10. Create the View

Now it is time to create our first view. As we mentioned earlier, we are forwarding to a JSP page named 'hello.jsp'. To begin with, we'll put it in the 'war' directory.
'springapp/war/hello.jsp':
<html>
  <head><title>Hello :: Spring Application</title></head>
  <body>
    <h1>Hello - Spring Application</h1>
    <p>Greetings.</p>
  </body>
</html>

1.11. Compile and deploy the application

Run the 'deploy' Ant target (which invokes the 'build' target), and then run the 'reload' task of the 'build.xml' file. This will force a build and reload of the application in Tomcat. We have to check the Ant output and the Tomcat logs for any possible deployment errors – such as typos in the above files or missing classes or jar files.
Here is a sample output from the Ant build:
$ ant deploy reload
Buildfile: build.xml

build:
    [mkdir] Created dir: /Users/trisberg/Projects/springapp/war/WEB-INF/classes
    [javac] Compiling 1 source file to /Users/trisberg/Projects/springapp/war/WEB-INF/classes

deploy:
     [copy] Copying 7 files to /Users/trisberg/apache-tomcat-5.5.17/webapps/springapp

BUILD SUCCESSFUL
Total time: 3 seconds
$ ant reload
Buildfile: build.xml

reload:
   [reload] OK - Reloaded application at context path /springapp

BUILD SUCCESSFUL
Total time: 2 seconds
And here is an excerpt from the Tomcat 'catalina.out' log file.
Oct 30, 2007 11:43:09 PM org.springframework.web.servlet.FrameworkServlet initServletBean
INFO: FrameworkServlet 'springapp': initialization started
Oct 30, 2007 11:43:09 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.web.context.support.XmlWebApplicationContext@6576d5: display name 
[WebApplicationContext for namespace 'springapp-servlet']; startup date [Tue Oct 30 23:43:09 GMT 2007]; 
...
...
Oct 30, 2007 11:43:09 PM org.springframework.web.servlet.FrameworkServlet initServletBean
INFO: FrameworkServlet 'springapp': initialization completed in 150 ms

1.12. Try out the application

Let's try this new version of the application.
Open a browser and browse to http://localhost:8080/springapp/hello.htm.

The updated application

1.13. Final Snapshot



The project directory structure at the end of part 1