AuthorsThomas Risberg, Rick Evans, Portia Tung Adapted by Arulazi Dhesiaseelan for NetBeans/GlassFish 2.5 3. The application we are building 1. Basic Application and Environment Setup 1.1. Create the NetBeans Spring project 1.3. Deploy the application to GlassFish 1.4. Check the application works 1.5. Download the Spring Framework 1.6. Modify 'web.xml' in the 'WEB-INF' directory 1.7. Copy libraries to 'WEB-INF/lib' 1.9. Write a test for the Controller 1.11. Compile and deploy the application 2. Developing and Configuring the Views and the Controller 2.1. Configure JSTL and add JSP header file 2.3. Decouple the view from the controller 3. Developing the Business Logic 3.1. Review the business case of the Inventory Management System 3.2. Add some classes for business logic 4. Developing the Web Interface 4.1. Add reference to business logic in the controller 4.2. Modify the view to display business data and add support for message bundle 4.3. Add some test data to automatically populate some business objects 5. Implementing Database Persistence 5.1. Create database startup script 5.2. Create table and test data scripts 5.3. Run scripts and load test data 5.4. Create a Data Access Object (DAO) implementation for JDBC 5.5. Implement tests for JDBC DAO implementation 6. Integrating the Web Application with the Persistence Layer 6.3. Create new application context for service layer configuration 6.4. Add transaction and connection pool configuration to application context This document is a step-by-step guide on how to develop a web application from scratch using the Spring Framework. Only a cursory knowledge of Spring itself is assumed, and as such this tutorial is ideal if you are learning or investigating Spring. Hopefully by the time you have worked your way through the tutorial material you will see how the constituent parts of the Spring Framework, namely Inversion of Control (IoC), Aspect-Oriented Programming (AOP), and the various Spring service libraries (such as the JDBC library) all fit together in the context of a Spring MVC web application. Spring provides several options for configuring your application. The most popular one is using XML files. This is also the traditional way that has been supported from the first release of Spring. With the introduction of Annotations in Java 5, we now have an alternate way of configuring our Spring applications. The new Spring 2.5 release introduces extensive support for using Annotations to configure a web application. This document uses the traditional XML style for configuration. We are working on an "Annotation Edition" of this document and hope to publish it in the near future. Please note that we are not going to cover any background information or theory in this tutorial; there are plenty of books available that cover the areas in depth; whenever a new class or feature is used in the tutorial, forward pointers to the relevant section(s) of the Spring reference documentation are provided where the class or feature is covered in depth. The following list details all of the various parts of the Spring Framework that are covered over the course of the tutorial. · Inversion of Control (IoC) · The Spring Web MVC framework · Data access with JDBC · Unit and integration testing · Transaction management The following prerequisite software and environment setup is assumed. You should also be reasonably comfortable using the following technologies. · Java SDK 1.5/1.6 · Ant 1.7 · Spring Netbeans Module Release 1.1 · GlassFish V2 UR1 · NetBeans 6.0 NetBeans IDE 6.0 Full Pack (http://www.netbeans.org) provides an excellent environment for web application development. The Ant build scripts are omitted from this discussion as they are automatically generated by the IDE. The Spring plugin module for NetBeans should be installed prior to start of this project, You may of course use pretty much any variation or version of the above software. If you want to use IntelliJ instead of NetBeans or Jetty instead of GlassFish, then many of the tutorial steps will not translate directly to your environment but you should be able to follow along anyway. The application we will be building from scratch over the course of this tutorial is a very basic inventory management system. This inventory management system is severely constrained in terms of scope; find below a use case diagram illustrating the simple use cases that we will be implementing. The reason why the application is so constrained is so that you can concentrate on the specifics of Spring Web MVC and Spring, and not the finer details of inventory management. Use case diagram of the inventory management system We will start by setting up the basic project directory structure for our application, downloading the required libraries, setting up our Ant build scripts, etc. The first step gives us a solid foundation on which to develop the application proper in parts 2, 3, and 4. Once the basic setup is out of the way, Spring itself will be introduced, starting with the Spring Web MVC framework. We will use Spring Web MVC to display the inventoried stock, which will involve writing some simple Java classes and some JSPs. We will then move onto introducing persistent data access into our application, using Spring's Simple JDBC support. By the time we have finished all of the steps in the tutorial, we will have an application that does basic inventory management, including listing stock and permitting the price increase of such stock. We
are going to need a place to keep all the source and other files we will be
creating, so let's create a project named Project Creation Wizard: Step 1 of 3 Enter the project name as “springapp” and select “GlassFish V2 UR1” as the Server and click Next. Project Creation Wizard: Step 2 of 3 Select the framework as “Spring Framework 2.5” and enter “springapp” as the dispatcher name and click Finish. Project Creation Wizard: Step 3 of 3 Find below a screen shot of what your project directory structure must look like after following the above instructions. (The screen shot shows the project directory structure inside the NetBeans IDE: you do not need to use the NetBeans IDE to complete this tutorial successfully, but using NetBeans will make it much easier to follow along.) Since
we are creating a web application, let's start by updating the basic JSP page
Just to have a complete web application,
let's update the
Right click the project and click Build. It builds the web application. Build the web application Right click the project and click Undeploy and Deploy. It deploys the web application to GlassFish server. Deploy the web application The server is already started when the application was deployed in the previous step. 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 If you have not already downloaded the Spring Framework, now is the time to do so. We are currently using the 'Spring Framework 2.5' release that can be downloaded from http://www.springframework.org/download. Unzip this file somewhere as we are going to use several files from this download later on. This completes the setup of the environment that is necessary, and now we can start actually developing our Spring Framework MVC application.
Go to the
Next, update the file
The spring libraries are copied when the project is first created. These jars will be deployed to the server and they are also used during the build process. Create your
This is a very basic
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 use the
‘Test Packages’ for this. This is where all our tests will go in a package
structure that will mirror the source tree in Create a test class called
We can use the IDE to run the JUnit test (and all the tests we're going to write). Make sure the junit jars are present in the ‘Test Libraries’ location of the project. Now run the JUnit by right clicking the testcase and select ‘Run File’ and the test should pass. Running JUnit test within the IDE 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. Now it is time to create our first view.
As we mentioned earlier, we are forwarding to a JSP page named
Refer section 1.3 for building and deploying the web application from an IDE. Let's try this new version of the application. Open a browser and browse to http://localhost:8080/springapp/hello.htm. Let's take quick look at the parts of our application that we have created so far. ·
An introduction
page, ·
A DispatcherServlet (front controller) with a corresponding
· A page controller, HelloController, with limited functionality – it just returns a ModelAndView. We currently have an empty model and will be providing a full model later on. · A unit test class for the page controller, HelloControllerTests, to verify the name of the view is the one we expect. ·
A view,
Find below a screen shot of what your project directory structure must look like after following the above instructions.
The project directory structure at the end of part 1 This is Part 2 of a step-by-step tutorial on how to develop a web application from scratch using the Spring Framework. In Part 1 we configured the environment and set up a basic application that we will now flesh out. This is what we have implemented so far: ·
An introduction
page, ·
A DispatcherServlet (front controller) with a corresponding
· A page controller, HelloController, with limited functionality – it just returns a ModelAndView. We currently have an empty model and will be providing a full model later on. · A unit test class for the page controller, HelloControllerTests, to verify the name of the view is the one we expect. ·
A view,
We will be using the JSP Standard Tag
Library (JSTL), so let's make sure We will be creating a 'header' file that
will be included in every JSP page that we're going to write. We ensure the same
definitions are included in all our JSPs simply by including the header file.
We're also going to put all JSPs in a directory named First we create the header file for inclusion in all the JSPs we create.
Now we can update
Move
Before we update the location of the JSP
in our controller, let's update our unit test class first. We know we need to
update the view's resource reference with its new location
Next, we run the JUnit by right clicking the testcase and select ‘Run File’ and the test should fail. Running JUnit test within the IDE Now we update
We rerun our JUnit and the test passes. Remember that the Right now the controller specifies the
full path of the view, which creates an unnecessary dependency between the
controller and the view. Ideally we would like to map to the view using a
logical name, allowing us to switch the view without having to change the
controller. You can set this mapping in a properties file if you like using a
We update the view name in the controller
test class
We then remove the prefix and suffix from
the view name in the controller, leaving the controller to reference the view by
its logical name
Rerun the test and it should now pass. Let's compile and deploy the application and verify the application still works.
Let's take quick look at what we have created in Part 2. ·
A header file
These are the existing artifacts we have changed in Part 2. · The HelloControllerTests has been updated repeatedly as we make the controller reference the logical name of a view instead of its hard coded name and location. ·
The page
controller, HelloController, now references the view by its logical
view name through the use of the 'InternalResourceViewResolver' defined in Find below a screen shot of what your project directory structure must look like after following the above instructions. This is Part 3 of a step-by-step tutorial on how to develop a Spring application. In this section, we will adopt a pragmatic Test-Driven Development (TDD) approach for creating the domain objects and implementing the business logic for our inventory management system. This means we'll "code a little, test a little, code some more then test some more". In Part 1 we configured the environment and set up a basic application. In Part 2 we refined the application by decoupling the view from the controller. Spring is about making simple things easy and the hard things possible. The fundamental construct that makes this possible is Spring's use of Plain Old Java Objects (POJOs). POJOs are essentially plain old Java classes free from any contract usually enforced by a framework or component architecture through subclassing or the implementation of interfaces. POJOs are plain old objects that are free from such constraints, making object-oriented programming possible once again. When you are working with Spring, the domain objects and services you implement will be POJOs. In fact, almost everything you implement should be a POJO. If it's not, you should be sure to ask yourself why that is. In this section, we will begin to see the simplicity and power of Spring. In our inventory management system, we have the concept of a product and a service for handling them. In particular, the business has requested the ability to increase prices across all products. Any decrease will be done on an individual product basis, but this feature is outside the scope of our application. The validation rules for price increase are: · The maximum increase is limited to 50%. · The minimum increase must be greater than 0%. Find below a class diagram of our inventory management system. Let's now add some business logic in the
form of a First we implement the
Now we write the unit tests for our
Next we create the
Let's create the
Before we implement the methods in
To write effective tests, you have to
consider all the possible pre- and post-conditions of a method being tested as
well as what happens within the method. Let's start by testing a call to
Rerun all the JUnit tests and the test
should fail as Next we implement a test for retrieving a
list of stub products populated with test data. We know that we'll need to
populate the products list in the majority of our test methods in
Rerun all the Junit tests and our two tests should fail. We go back to the
Rerun the Junit tests and all our tests should pass. We proceed by implementing the following
tests for the · The list of products is null and the method executes gracefully. · The list of products is empty and the method executes gracefully. · Set a price increase of 10% and check the increase is reflected in the prices of all the products in the list.
We return to
Rerun the JUnit tests and all our tests should pass. *HURRAH* JUnit has a saying: “keep the bar green to keep the code clean.” For those of you running the tests in an IDE and are new to unit testing, we hope you're feeling imbued with a sense of greater sense of confidence and certainty that the code is truly working as specified in the business rules specification and as you intend. We certainly do. We're now ready to move back into the web
layer to put a list of products into our
Let's take quick look at what we did in Part 3. · We implemented a domain object Product and a service interface ProductManager and concrete class SimpleProductManager all as POJOs. · We wrote unit tests for all the classes we implemented. · We didn't write a line of code to do with Spring. This is an example of how non-invasive the Spring Framework really is. One of its core aims is to enable developers to focus on tackling the most important task of all: to deliver value by modelling and implementing business requirements. Another of its aims is to make following best practices easy, such as implementing services using interfaces and unit testing as much as is pragmatic given project constraints. Over the course of this tutorial, you'll see the benefits of designing to interfaces come to life. Find below a screen shot of what your project directory structure must look like after following the above instructions. This is Part 4 of a step-by-step account of how to develop a web application from scratch using the Spring Framework. In Part 1 we configured the environment and set up a basic application. In Part 2 we refined the application that we will build upon. Part 3 added all the business logic and unit tests. It's now time to build the actual web interface for the application. First of all, let's rename our
We will also need to modify the
InventoryControllerTests to supply a ProductManager and extract the value for
Using the JSTL
It's time to add a
We create a
Now re-build the application and deploy it. Let's try accessing this new version of the application and you should see the following: To provide an interface in the web
application to expose the price increase functionality, we add a form that will
allow the user to enter a percentage value. This form uses a tag library named
We also have to declare this taglib in a
page directive in the jsp file, and then start using the tags we have thus
imported. Add the JSP page
This next class is a very simple JavaBean class, and in our case there is a single property with a getter and setter. This is the object that the form will populate and that our business logic will extract the price increase percentage from.
The following validator class gets control
after the user presses submit. The values entered in the form will be set on the
command object by the framework. The
Now we need to add an entry in the
Next, let's take a look at the controller
for this form. The
We are also adding some messages to the
Compile and deploy all this and after reloading the application we can test it. This is what the form looks like with errors displayed. Finally, we will add a link to the price
increase page from the Now, re-deploy and try the new price increase feature. Let's look at what we did in Part 4. · We renamed our controller to InventoryController and gave it a reference to a ProductManager so we could retrieve a list of products to display. · Next we modified the JSP page to use a message bundle for static text and also added a forEach loop to show the dynamic list of products. · Then we defined some test data to populate business objects we modified the JSP page to use a message bundle for static text and also added a forEach loop to show the dynamic list of products. · Next we modified the JSP page to use a message bundle for static text and also added a forEach loop to show the dynamic list of products. · After this worked we created a form to provide the ability to increase the prices. Next we modified the JSP page to use a message bundle for static text and also added a forEach loop to show the dynamic list of products. · Finally we created the form controller and a validator and deployed and tested the new features. Find below a screen shot of what your project directory structure must look like after following the above instructions. This is Part 5 of a step-by-step account of how to develop a web application from scratch using the Spring Framework. In Part 1 we configured the environment and set up a basic application. In Part 2 we refined the application that we will build upon. Part 3 added all the business logic and unit tests and Part 4 developed the web interface. It is now time to introduce database persistence. We saw in the earlier parts how we loaded some business objects using bean definitions in a configuration file. It is obvious that this would never work in real life – whenever we re-start the server we are back to the original prices. We need to add code to actually persist these changes to a database. Before we can start developing the persistence code, we need a database. We are planning on using HSQL, which is a good open source database written in Java. This database is distributed with Spring, so it is already part of the web application's lib directory. We will use HSQL in standalone server mode. That means we will have to start up a separate database server instead of relying on an embedded database, but it gives us easier access to see changes made to the database when running the web application. We need a script or batch file to start
the database. Create a For Linux/Mac OS X add:
Don't forget to change the execute permission by running 'chmod +x server.sh'. For Windows add:
Now you can open a command window, change
to the First, lets review the SQL statement needed to create the table. We create the file 'create_products.sql' in the db directory.
Now we need to add our test data. Create the file 'load_data.sql' in the db directory.
In the following section we will see how we can run these SQL scripts from the IDE.
We will create tables and populate them with test data using IDE’s built-in SQL capabilities. To use this we need to add database connection to the HSQL database. Configuring a database connection Next we execute the create table and load test data scripts using the Run SQL option from the IDE. Executing the SQL scripts Select the data from the table using the SQL command window. Executing the select query from SQL command window Now you can execute createTable and loadData to prepare the test data we will use later. Begin with creating a new
We'll follow this with a class called
Let's go over the two DAO methods in this
class. Since we are extending The first method, The ProductMapper implements the
The second method saveProduct is also
using the We need to store the value of the primary key for each product in the Product class. This key will be used when we persist any changes to the object back to the database. To hold this key we add a private field named 'id' complete with setters and getters to Product.java.
This completes the Simple JDBC implementation of our persistence layer.
Time to add tests for the JDBC DAO
implementation. Spring provides an extensive testing framework that supports
JUnit 3.8 and 4 as well as TestNG. We can't cover all of that in this guide but
we will show a simple implementation of the JUnit 3.8 specific support. We need
to add the jar file containing the Spring test framework to our project. Add
Now we can create our test class. By
extending
We don't have the application context file
that is loaded for this test yet, so let's create this file in the
We have defined a
Since we added a configuration file to the
We should now have enough for our tests to run and pass but it's a good practice to separate any integration tests that depend on a live database from the rest of the tests. Time to run this Junit by right clicking the testcase and select ‘Run File’ to see if the tests pass.
We have now completed the persistence layer and in the next part we will integrate it with our web application. But first, lets quickly summarize hat we accomplished in this part. · First we configured our database and created start-up scripts. · We created scripts to use when creating the table and also to load some test data. · Next we added some tasks to our build script to run when we needed to create or delete the table and also when we needed to add test data or delete the data. · We created the actual DAO class that will handle the persistence work using Spring's SimpeJdbcTemplate. · Finally we created unit or more accurately integration tests and corresponding ant targets to run these tests. Below is a screen shot of what your project directory structure should look like after following the above instructions. This is Part 6 of a step-by-step account of how to develop a web application from scratch using the Spring Framework. In Part 1 we configured the environment and set up a basic application. In Part 2 we refined the application that we will build upon. Part 3 added all the business logic and unit tests and Part 4 developed the web interface. In Part 5 we developed the persistence layer. It is now time to integrate all this into a complete web application. If we structured our application properly,
we should only have to change the service layer classes to take advantage of the
database persistence. The view and controller classes should not have to be
modified, since they should be unaware of any implementation details of the
service layer. So let's add the persistence to the ProductManager
implementation. We modify the
We rewrote the
And here is the modified
We also need to modify the
We saw earlier that it was fairly easy to modify the service layer to use the database persistence. This was because it is decoupled from the web layer. It's now time to decouple or configuration of the service layer from the web layer as well. We will remove the productManager configuration and the list of products from the springapp-servlet.xml configuration file. This is what this file looks like now:
We still need to configure the service
layer and we will do that in its own application context file. This file is
called
Now we create a new
Any time you persist data in a database its best to use transactions to ensure that all your updates are perform or none are completed. You want to avoid having half your updates persisted while the other half failed. Spring provides an extensive range of options for how to provide transaction management. The reference manual covers this in depth. Here we will make use of one way of providing this using AOP (Aspect Oriented Programming) in the form of a transaction advice and an ApectJ pointcut to define where the transactions should be applied. If you are interested in how this works in more depth, take a look at the reference manual. We are using the new namespace support introduced in Spring 2.0. The "aop" and "tx" namespaces make the configuration entries much more concise compared to the traditional way using regular "<bean>" entries. The pointcut applies to any method called on the ProductManager interface. The advice is a transaction advice that applies to methods with a name starting with 'save'. The default transaction attributes of REQUIRED applies since no other attribute was specified. The advice also applies "r |
























