BUY THIS BOOK
Add to Cart

Print Book $29.95


Add to Cart

PDF $23.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £20.95

What is this?

Looking to Reprint or License this content?


Spring: A Developer's Notebook
Spring: A Developer's Notebook

By Bruce A. Tate, Justin Gehtland
Book Price: $29.95 USD
£20.95 GBP
PDF Price: $23.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Getting Started
I'm a bona fide weekend extremist. I've done some pretty crazy things on a mountain bike, by layman's standards, and I love to kayak. I've been in serious trouble exactly once. I was on a river called the Piedra that I'd never run before, with new equipment and new techniques in my head. In kayaking, simplicity and speed are life, but I was tentative and slow. Instead of attacking the river, it attacked me, and I swam through three distinct class IV rapids, and was very lucky to emerge unscathed.
Spring is the most popular of a new breed of so-called lightweight con-tainers. When you add all of the supporting frame-works, Spring is fairly hefty, but "lightweight" refers to all of the crud that usually accompanies code that you put into the container.
Many teachers and consultants write about dependencies like mayonnaise that's been left out in the sun too long, but if your application is to do anything interesting at all, it must have dependencies. The trick is to identify important dependencies, and deal with them in the right way. The way that you manage them will determine whether your application is easy to maintain, extend, and test. In this book, we'll do a mountain bike reservation system. A sports shop could use such a system for bike rentals. We'll start small, with all of the dependencies hardwired, to make sure that our infrastructure works. Then, we'll loosen the coupling with Spring, and progressively add persistence, a web-based presentation layer, declarative transactions, and other services.
For me, Spring style development is iterative. The first couple of labs are all about ramping up our infrastructure slowly. The first example will make sure that we have a working Java environment, and it will start to build our core model. Each of the first few examples ramp up one small part of your environment, making it easy to troubleshoot anything that might go wrong.
Start with two classes in a single directory. One's a mountain bike, and the other is a registry that holds bikes. Call it a façade. You'll add bikes to the store within the façade constructor, and then print them all out using a third primitive class. (All of the classes shown in the book reside in a single package,
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Building Two Classes with a Dependency
Many teachers and consultants write about dependencies like mayonnaise that's been left out in the sun too long, but if your application is to do anything interesting at all, it must have dependencies. The trick is to identify important dependencies, and deal with them in the right way. The way that you manage them will determine whether your application is easy to maintain, extend, and test. In this book, we'll do a mountain bike reservation system. A sports shop could use such a system for bike rentals. We'll start small, with all of the dependencies hardwired, to make sure that our infrastructure works. Then, we'll loosen the coupling with Spring, and progressively add persistence, a web-based presentation layer, declarative transactions, and other services.
For me, Spring style development is iterative. The first couple of labs are all about ramping up our infrastructure slowly. The first example will make sure that we have a working Java environment, and it will start to build our core model. Each of the first few examples ramp up one small part of your environment, making it easy to troubleshoot anything that might go wrong.
Start with two classes in a single directory. One's a mountain bike, and the other is a registry that holds bikes. Call it a façade. You'll add bikes to the store within the façade constructor, and then print them all out using a third primitive class. (All of the classes shown in the book reside in a single package, com.springbook, unless otherwise specified.)
Example 1-1 shows the bike.
Example 1-1. Bike.java
public class Bike {
    private String manufacturer;
    private String model;
    private int frame;
    private String serialNo;
    private double weight;
    private String status;

    public Bike(String manufacturer, String model, int frame, 
                String serialNo, double weight, String status) {

        this.manufacturer = manufacturer;
        this.model = model;
        this.frame = frame;
        this.serialNo = serialNo;
        this.weight = weight;
        this.status = status;
    }

    public String toString( ) {
        return "Bike : " +
                "manufacturer -- " + manufacturer +
                "\n: model -- " + model +
                "\n: frame -- " + frame +
                "\n: serialNo -- " + serialNo +
                "\n: weight -- " + weight +
                "\n: status -- " + status +
                ".\n";
    }
    
    public String getManufacturer( ) { return manufacturer; }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    public String getModel( ) { return model; }

    public void setModel(String model) { this.model = model; }

    public int getFrame( ) { return frame; }

    public void setFrame(int frame) { this.frame = frame; }

    public String getSerialNo( ) { return serialNo; }

    public void setSerialNo(String serialNo) { this.serialNo = serialNo; }

    public double getWeight( ) { return weight; }

    public void setWeight(double weight) { this.weight = weight; }

    public String getStatus( ) { return status; }

    public void setStatus(String status) { this.status = status; }
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using Dependency Injection
When I begin to build any application, it's usually tightly coupled. That's okay. I can always refactor it later. In this example, I'll structure the application so that it will work with Spring when I add it. I introduce an interface to the façade layer, so that I can have a façade layer that implements several different strategies.
The first step to learning Spring is the dependency injection pattern. It's not complicated, but it's the central concept. It's different enough from the typical way that most people code that you'll want to get it down quickly.
Figure 1-1 shows a client and server prepared for dependency injection. A client uses another class that we'll call a service. The client has a property that accepts a service. The service is wrapped in an interface. The client can't see the implementation of the service. But this code is not yet loosely coupled: you still have to create the service somewhere. With dependency injection, a third-party, called the assembler or container, creates both the client and service, and then sets the value of aService (which is a reference to an instance of Service) to satisfy the dependency.
Figure 1-1: This client uses a service wrapped in an interface
Many see dependency injection for the first time and wonder, "What's the big deal? " After working with it some, they come to understand that this simple change can dramatically improve their code and ease future maintenance.
You probably already code this way in spots. You'll see how powerful this programming model can be when you use it in a framework that applies it in a consistent way across your application. Code made of decoupled components is easier to test, maintain, and understand.
You don't have to use a lightweight container to use this design pattern. To decouple with dependency injection, there are three steps:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Automating the Example
It's time for a little housekeeping. To go much further, you need to automate. You probably already use Ant. It's a standardized way to organize all of the tasks that you need to build your application. If you don't already use it, you need to.
Ant has become ubiquitous. In order to work with Java tools, you need to be able to speak the language. We're not going to provide yet another justification for Ant in this chapter, since you've probably read enough of them already.
You'll need to download an Ant distribution. You may as well use the one that comes with Spring (http://springframework.org/ ). To run all of the examples for this book, you'll want to get Spring version 1.1, or later. Follow all of the directions for your platform.
Next, you'll organize the directory structure in a way that's friendly for web applications and Spring. I recommend that you use the organization that you'll find with the Spring sample applications, so that you'll have a working example. These are the directories that you'll use:
src
This directory has the home for all of the source code in your application. As usual, you'll want the directory structure to mirror your package structure.
test
This directory has the home for all of your unit tests. We'll talk more about JUnit in the last lab.
db
This directory has the home for all database specific scripts, configuration, and code. Some of these will be configuration files, some will help set up a database with the correct schema, and some will help initialize the database with test data, if necessary. If you support multiple databases, each will have its own directory under
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Injecting Dependencies with Spring
You're almost through with the setup for Spring. It's time to download it and put it into action. In this lab, you'll replace the RentABikeAssembler object with Spring.
When I started using Spring instead of J2EE, it changed my life. I got more productive. My code got easier for me to write, and easier for my customers to understand. Since it was simpler, it often executed faster. It was also infinitely easier to refactor. In fact, I wrote a book about the value of lightweight frameworks like Spring, called Better, Faster, Lighter Java (O'Reilly).
You'll first have to download Spring. Go get it at http://www.springframework.org. That will point you to sourceforge, where you'll get the best version for your platform. We used Version 1.1. You will need to add a new folder to your project, war\WEB-INF\lib, and put the Spring libraries there (everything in the \dist folder of your Spring distribution).
Moving a well-designed plain-ordinary-Java-object (POJO) application to Spring is straightforward. It only takes three steps:
  • Refactor your code to take advantage of dependency injection. Model objects are beans, and services are aspects. Usually, you'll only have beans.
  • Remove the code that instantiates the objects and sets dependencies.
  • Build a configuration file describing your beans and aspects.
  • Access your code through Spring.
Since our individual parts are already built to take advantage of dependency injection, moving to Spring is an easy exercise. We simply replace our assembler with a Spring version, and provide a configuration file which will go in the \war\WEB-INF folder.
Example 1-9 shows the configuration file.
Example 1-9. RentABike-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    <bean id="rentaBike" class="ArrayListRentABike">
        <property name="storeName"><value>"Bruce's Bikes"</value></property>
    </bean>

    <bean id="commandLineView" class="CommandLineView">
        <property name="rentaBike"><ref bean="rentaBike"/></property>
    </bean>

</beans>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Writing a Test
We'll finish each chapter with a test. In fact, if you're a true believer in test-driven development, you should code your test cases first. Many of you bought this book because Spring can improve the testability of your applications. In fact, improving testability was one of the fundamental drivers of Spring's architecture from the beginning.
Automating your tests gives you more confidence that your code will work right, and will keep working right as you make changes. In fact, our managers are all reading the same books that say that it's expensive to keep large testing organizations in place. We've got to pick up the slack. There's no effective way to do that without automation. There's a big problem, though. Many of our current development architectures, like EJB and Struts, do not support testing very well. They're expensive to load, and hard to mock.
Spring changes all of that. Each object can run outside of the container. Further, since the container itself is so light, the startup cost is negligible. That's a huge win for you, if you want to test. Finally, Spring encourages designs with very loose coupling between components.
Think of a unit test as another client of your application. The test makes assertions about what should be true should the application be working correctly. For example, if you add an object to a list, the size should increase by one. Then, you can run the test standalone while you're building a new feature or debugging an old one. You can also run the tests as part of the overall build. If the tests fail, then the build fails.
Each test case is a subclass of TestCase. In Example 1-11, the test will be a client of the façade.
Example 1-11. RentABikeTest.java
public class RentABikeTest extends TestCase{

    private RentABike rentaBike;

    public void setUp( ) {
        rentaBike = new ArrayListRentABike("Bruce's Bikes");
    }
    
    public void testGetName( ) {
        assertEquals("Bruce's Bikes", rentaBike.getStoreName( ));
    }

    public void testGetBike( ) {
        Bike bike = rentaBike.getBike("11111");
        assertNotNull(bike);
        assertEquals("Shimano", bike.getManufacturer( ));
    }

    public void testGetBikes( ) {
        List bikes = rentaBike.getBikes( );
        assertNotNull(bikes);
        assertEquals(3, bikes.size( ));
    }
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Building a User Interface
I was hauling down a trail called Emma Long, and came up to a four-foot drop. In a split second, I had to make the decision of whether to jump the ledge, try to ride down it, or stop and get off my bike. I once read that in Austin, Texas, there are more broken mountain bike frames than any other place, per capita. Though I've never confirmed it, I believe it, because there are so many rocky trails with ledges that are small enough to handle sometimes with a cheap bike, but also big enough to snap the frame. Web-based user interface development is similar. It's easy to get started down that trail with a bike that's not quite up to the task. Often, it's the framework and organization of the code that's just behind the user interface that presents the biggest problem. In this chapter, you'll learn how Spring can help. We'll focus on Spring's Web MVC framework, but in the next chapter, we'll also show you how to integrate alternative frameworks, and even use rich clients.
In this first example, you'll learn how to build a simple user interface with Tomcat with Spring's Web MVC framework. You'll add a couple of screens to add bikes to the inventory of rental bikes. Then, we'll add a hardwired JSP that will let you add a new bike to the database.
Spring doesn't force you to use a full application server. Actually, you don't even have to build web-based applications. The requirement for Tomcat is really a requirement for some servlet container, purely because this application (not Spring) requires it.
Spring doesn't give you a servlet container. Instead, it just gives you a set of services that make it easier to build web applications.
Most projects simply don't need a full-blown J2EE container. One of the best things about Spring is that you can deploy it, in production, without paying for an application server, or the hardware that you'd need to run one. Tomcat will manage your servlets, provide an easy architecture for managing deployments, and let you manage its threading model.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Setting Up Tomcat
In this first example, you'll learn how to build a simple user interface with Tomcat with Spring's Web MVC framework. You'll add a couple of screens to add bikes to the inventory of rental bikes. Then, we'll add a hardwired JSP that will let you add a new bike to the database.
Spring doesn't force you to use a full application server. Actually, you don't even have to build web-based applications. The requirement for Tomcat is really a requirement for some servlet container, purely because this application (not Spring) requires it.
Spring doesn't give you a servlet container. Instead, it just gives you a set of services that make it easier to build web applications.
Most projects simply don't need a full-blown J2EE container. One of the best things about Spring is that you can deploy it, in production, without paying for an application server, or the hardware that you'd need to run one. Tomcat will manage your servlets, provide an easy architecture for managing deployments, and let you manage its threading model.
First, you'll go to http://jakarta.apache.org/tomcat. There, you'll find Apache Tomcat 5.0.27, which is the version that we're using for all of our examples. If you want to use something else, that's okay. You'll just need some type of servlet container that supports:
  • JSP Version 1.2 or higher
  • Servlet Version 2.3 or higher
Next, you'll modify the façade to the RentABike, so that you can do simple create/read/update/delete (CRUD) methods. Example 2-1 gives the new façade.
Example 2-1. RentABike.java
public interface RentABike {
    List getBikes( );
    Bike getBike(String serialNo); 
    void saveBike(Bike bike);
    void deleteBike(Bike bike);
    void setStoreName(String name);
    String getStoreName( );
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Building a View with Web MVC
In this example, you'll build a simple web-based user interface with Spring's Web MVC framework. You'll use the code that you've accumulated for RentABike for the business logic, you'll use Spring to help you organize and configure the application, and you'll deploy it on Tomcat.
If you've done this for any length of time, you probably recognize that you're barreling down a trail that will break your frame if you're not careful. This simple application is not the ideal structure for a web application. Changes in the application will trickle through the view, and changes in the view will require significant updates to your models. Experience has shown that it's better to have a model, view, and controller layer, with a variation of the model/view/controller (MVC) design pattern called model2, shown in Figure 2-1. This is the design that you'll be using in Spring's Web MVC, or most other MVC frameworks.
Figure 2-1: It's best to separate web applications into three distinct components: model, view, and controller
Like Struts, Web MVC lets you build applications with three distinct layers: the model, view, and controller. You'll also need to configure what you've done. Since you've already developed the model with the business logic (you'll specify the façade as your model), you're free to first concentrate on the view.

Section 2.2.1.1: The JSPs

For now, the view will be a thin JSP layer that lets you pick a bike from a list, then remove or edit it. You'll use another screen to add or edit bike information. We aren't focusing on formatting, since we're primarily interested in Spring's role. You'll use standard JSTL (available at http://java.sun.com/products/jsp/jstl/, or packaged with Spring). Add standard.jar, jstl.jar, c.tld and fmt.tld to your war\WEB-INF\lib folder. You'll link them through an
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Enhancing the Web Application
The code that you've seen so far begins to provide much needed organization with distinct models, views, and controllers. In this section, we'll add validation logic, a resolver, and input forms.
These enhancements will add better organization to your code and save you time and effort. Like many MVC frameworks, these classic enhancements make it easier to handle the classic flow of control that you generally get with web applications:
Resolvers
As your application grows, you'll want to refer to each page with a logical name rather than a full path. The resolver manages the details, like the extension and the path, letting you specify these details in your configuration.
Form
These input JSPs make it easy to manage user input, providing easy place holders for data, and a work flow for forms submission. Forms are separated into the view, and controller. The physical view can utilize a special Spring tag library to bind form fields to POJO properties.
Validators
These beans work with input forms to make it easy to handle business validation. They have no dependencies on Spring's Web MVC—you need only implement an interface—so it's easy to package your validation with your business logic.
These simple enhancements let you manage the flow of control in a manner that's consistent and organized. It also lets you keep code in a consistent place, and keep coupling to a bare minimum.
We're going to code our enhancements in two distinct steps. First, we'll configure the resolver. To do that, we're going to need to change the configuration in the rentaBikeApp-Servlet.xml by adding the following element (Example 2-13).
Example 2-13.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Running a Test
Now that you've implemented a few simple views, it's time to do a test. We'll simply do a lightweight request, outside of the servlet container.
Part of the beauty of Web MVC is that it's much easier to test. We'll show you a couple of simple test cases that exercise the core of the user interface pretty well.
In this case, you're simply going to invoke the controller, and make sure that you get the appropriate model back. First, you can code a simple JUnit test case that invokes the BikesController (Example 2-20).
Example 2-20. ControllerTest.java
public class ControllerTest extends TestCase {

    private ApplicationContext ctx;

    public void setUp( ) throws Exception {
        ctx = new FileSystemXmlApplicationContext(
           "war/WEB-INF/rentaBikeApp-servlet.xml");
    }

    public void testBikesController( ) throws Exception {
        BikesController controller = (BikesController) 
           ctx.getBean("bikesController");
        ModelAndView mav = controller.handleRequest(null, null);
        RentABike store = (RentABike) mav.getModel( ).get("rentaBike");
        assertNotNull(store);
        assertTrue(store.getBikes( ).size( ) == 3);
    }
}
You have to load up the configuration file in order to test that Spring is loading the beans correctly. Spring provides the FileSystemXmlApplicationContext class to load the context configuration explicitly.
Next, we'll want to test the validator to make sure it catches errors appropriately (Example 2-21).
Example 2-21. ControllerTest.java
public void testBikeValidator( ) throws Exception {
        BikeValidator v = (BikeValidator) ctx.getBean("bikeValidator");
        Bike bike = new Bike("test", "test", 1, "test", 2.00, "test");
        Errors errs = new BindException(bike, "bike");
        v.validate(bike, errs);
        assertFalse(errs.hasErrors( ));
        bike = new Bike( );
        errs = new BindException(bike, "bike");
        v.validate(bike, errs);
        assertTrue(errs.hasErrors( ));
    }
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Integrating Other Clients
I'd like to say that I love everything about kayaking, but that's not quite true. I hate dragging my boat to the put-in, and back out again. In fact, if I have to hike more than a couple of miles to get where I'm going, I'm probably not going to run the river. It's not that I hate hiking, or even backpacking. It's just that those in my sport don't hike with our boats enough, so we haven't usually thought through the problem.
New Spring code gets introduced in the sandbox. When the code matures, it's added to the main Spring project.
In the first example, you'll build a portion of our user interface with Java's most popular user interface framework, Struts. You'll also learn how to wire it to Spring.
If you're starting a new project, you may decide to choose an alternative to Struts. We believe that emerging MVC frameworks improve the user and developer experience, but Struts is still the most popular choice.
The Struts user interface looks much like the web MVC interface. You'll configure a central dispatcher. The dispatcher will send requests to a controller, and the controller will invoke business logic in the form of actions.
First, you need to configure Struts. That happens in two places: web.xml configures your central dispatcher and struts-config.xml manages the Struts Controller. Example 3-1 shows web.xml.
Example 3-1. web.xml
<!DOCTYPE web-app
   PUBLIC  "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
   "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>

    <display-name>RentABike</display-name>
    <description>
        Renting bikes for fun and profit.
    </description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          /WEB-INF/rentABikeApp-servlet.xml
        </param-value>
    </context-param>

    <servlet>
       <servlet-name>SpringContext</servlet-name>
       <servlet-class>
           org.springframework.web.context.ContextLoaderServlet
       </servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
       <servlet-name>RentABike</servlet-name>
       <servlet-class>
           org.apache.struts.action.ActionServlet
       </servlet-class>
       <init-param>
          <param-name>config</param-name>
          <param-value>/WEB-INF/struts-config.xml</param-value>
       </init-param>
       <init-param>
          <param-name>validate</param-name>
          <param-value>true</param-value>12
       </init-param>
       <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
       <servlet-name>RentABike</servlet-name>
       <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>
            start.html
        </welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>

   <listener>
        <listener-class>
            org.springframework.web.util.Log4jConfigListener
        </listener-class>
    </listener>

    <taglib>
        <taglib-uri>/spring</taglib-uri>
        <taglib-location>/WEB-INF/spring.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
        <taglib-location>/WEB-INF/c.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>/struts</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    </taglib>

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

</web-app>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Building a Struts User Interface
In the first example, you'll build a portion of our user interface with Java's most popular user interface framework, Struts. You'll also learn how to wire it to Spring.
If you're starting a new project, you may decide to choose an alternative to Struts. We believe that emerging MVC frameworks improve the user and developer experience, but Struts is still the most popular choice.
The Struts user interface looks much like the web MVC interface. You'll configure a central dispatcher. The dispatcher will send requests to a controller, and the controller will invoke business logic in the form of actions.
First, you need to configure Struts. That happens in two places: web.xml configures your central dispatcher and struts-config.xml manages the Struts Controller. Example 3-1 shows web.xml.
Example 3-1. web.xml
<!DOCTYPE web-app
   PUBLIC  "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
   "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>

    <display-name>RentABike</display-name>
    <description>
        Renting bikes for fun and profit.
    </description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          /WEB-INF/rentABikeApp-servlet.xml
        </param-value>
    </context-param>

    <servlet>
       <servlet-name>SpringContext</servlet-name>
       <servlet-class>
           org.springframework.web.context.ContextLoaderServlet
       </servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
       <servlet-name>RentABike</servlet-name>
       <servlet-class>
           org.apache.struts.action.ActionServlet
       </servlet-class>
       <init-param>
          <param-name>config</param-name>
          <param-value>/WEB-INF/struts-config.xml</param-value>
       </init-param>
       <init-param>
          <param-name>validate</param-name>
          <param-value>true</param-value>12
       </init-param>
       <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
       <servlet-name>RentABike</servlet-name>
       <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>
            start.html
        </welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>

   <listener>
        <listener-class>
            org.springframework.web.util.Log4jConfigListener
        </listener-class>
    </listener>

    <taglib>
        <taglib-uri>/spring</taglib-uri>
        <taglib-location>/WEB-INF/spring.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
        <taglib-location>/WEB-INF/c.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>/struts</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    </taglib>

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

</web-app>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using JSF with Spring
In this section you'll see how to use JavaServer Faces and Spring together. Then we'll see how you can use the JSF expression language to access Spring beans.
JSF, like Spring MVC and Tapestry, is a second-generation web application framework. The first generation, represented by frameworks such as Struts, have taught us a lot over the past three or four years, and better frameworks have evolved as a result. For example, both JSF and Tapestry have component models, which makes it easier to extend those frameworks and share that work with others.
JSF, Tapestry, and Spring MVC also support value bindings—wiring HTML elements (in the case of Spring MVC) or components (JSF and Tapestry) to JavaBean properties. In that simple mechanism lies a lot of power. More about that later...
In the first example, you'll implement Bruce's Bike Shop using JSF and Spring.
The JSF version of Bruce's Bike Store looks nearly identical to the Struts and Spring MVC versions, as you can see from Figure 3-3.
Figure 3-2: JSF version of the main page
You can dive right into the JSF version of bikes.jsp:
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<html>
   <f:view>
      <head>
         <title>
            <h:outputText value="#{rentABike.storeName}"/>
            
These tags are from the JSF tag libraries.
         </title>
      </head>

      <body>
         <h1><h:outputText value="#{rentABike.storeName}"/></h1>

         <h:outputText value="Edit a bike"/>

         <h:form>
            <h:dataTable value="#{rentABike.bikes}" var="bike">
               <h:column>
                  <h:commandLink action="#{editBikeController.editBike}">
                     <h:outputText 
                value="#{bike.manufacturer} - #{bike.model}"/>

                     <f:param name="bikeSerialNo" value="#{bike.serialNo}"/>
                  </h:commandLink>
               </h:column>
            </h:dataTable>

            <h:outputText value="<br/><br/>" escape="false"/>

            <h:commandLink action="#{editBikeController.newBike}">
               <h:outputText value="Add a new bike"/>
            </h:commandLink>
         </h:form>
      </body>
   </f:view>
</html>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Integrating JSF with Spring
Spring comes with a JSF variable resolver that lets you use JSF and Spring together. You can access Spring beans using JSF and vice versa. Integrating JSF and Spring lets you tap into the capabilities of two of the most powerful server-side Java frameworks.
You already did! In the previous example you used value bindings to bind JSF components to model objects. For example, in /bike.jsp, you did this:
         ...
         <h:form>
            <h:dataTable value="#{rentABike.bikes}" var="bike">
               <h:column>
                  ...
               </h:column>
            </h:dataTable>
            ...
         </h:form>
         ...
The #{rentABike.bikes} value binding references the bikes property of the bean named rentABike. Recall that previously, the rentABike bean was defined in a Spring configuration file, like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dt\
d/spring-beans.dtd">

<beans>
    <bean name="rentABike" class="com.springbook.ArrayListRentABike">
        <property name="storeName"><value>Bruce's Bikes</value></property>
    </bean>

    ...
</beans>
Things are no different in the JSF version of Bruce's Bike Shop, which means that the JSF expression #{rentABike.bikes} accesses a Spring bean. That's made possible by the DelegatingVariableResolver from the org.springframework.web.jsf package. You declare that variable resolver, which extends the JSF expression language to include references to Spring beans, in the faces configuration file:
<faces-config>
   <application>
      <variable-resolver>
         org.springframework.web.jsf.DelegatingVariableResolver
      </variable-resolver>
   </application>
   ...
</faces-config>
You saw how easy it is to integrate JSF and Spring. You can access Spring beans with the JSF expression language. That seamless integration makes it easy to use these two powerful frameworks together.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Using JDBC
On my first trip down the Cossatot River, the first two sections were easy and beautiful, but I couldn't enjoy them fully. I'd never really been on a class IV rapid, and I'd read that section three would start out with vengeance: five waterfalls ranging from six to ten feet, with the coup de grace being the fourth drop, called Washing Machine. I unintentionally ran two of the five backwards. But every advanced paddler needs to start somewhere, and I became addicted.
If you don't already have a relational database, it's time to set one up, define the schema for our application, and tweak our Ant build appropriately. Don't worry. It will go quickly. We'll use MySQL. You can then define some scripts that build the schema, and an Ant task to create the database from a script.
I'm directionally challenged, but kayakers have a tremendous advantage that most hikers don't share. Hikers can get easily lost as they take on more advanced hikes. My rivers don't move. They stay in the river beds, and flow one direction. I never have to worry about getting lost, as long as I can find the put-in and the take-out. Spring is like the river that lends structure and direction to your journey. It doesn't provide the database or transactions or remoting, but makes those services more consistent and easier to use.
First, you'll get and install MySQL. You can find it at http://mysql.org. Download it and follow the installation directions. Make sure to pay special attention to the instructions for initializing and modifying the user accounts for the installation; the instructions can vary greatly from one version to the next.
Start the MySQL daemon and make sure things are working by creating a database, as in Example 4-1.
Example 4-1. Using mysql client to list databases
mysql> create database bikestore;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+------------+
| Database   |
+------------+
| bikestore  |
| mysql      |
| test       |
+------------+
3 rows in set (0.00 sec)
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Setting Up the Database and Schema
If you don't already have a relational database, it's time to set one up, define the schema for our application, and tweak our Ant build appropriately. Don't worry. It will go quickly. We'll use MySQL. You can then define some scripts that build the schema, and an Ant task to create the database from a script.
I'm directionally challenged, but kayakers have a tremendous advantage that most hikers don't share. Hikers can get easily lost as they take on more advanced hikes. My rivers don't move. They stay in the river beds, and flow one direction. I never have to worry about getting lost, as long as I can find the put-in and the take-out. Spring is like the river that lends structure and direction to your journey. It doesn't provide the database or transactions or remoting, but makes those services more consistent and easier to use.
First, you'll get and install MySQL. You can find it at http://mysql.org. Download it and follow the installation directions. Make sure to pay special attention to the instructions for initializing and modifying the user accounts for the installation; the instructions can vary greatly from one version to the next.
Start the MySQL daemon and make sure things are working by creating a database, as in Example 4-1.
Example 4-1. Using mysql client to list databases
mysql> create database bikestore;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+------------+
| Database   |
+------------+
| bikestore  |
| mysql      |
| test       |
+------------+
3 rows in set (0.00 sec)
Your application is going to talk to MySQL through a JDBC driver. You've got to tell the JVM how to find it. You'll want to download the latest release version of the Mysql Connector/J library and make it available to your project's classpath. In this case, we've copied it into the /lib folder underneath the main project folder.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using Spring JDBC Templates
Although persistence frameworks like EJB container-managed persistence, JDO, and Hibernate have attracted fans at various times, JDBC remains the bread-and-butter of database development with Java. You can write it all yourself, or you can use some frameworks to help manage the details. Spring lets you do JDBC development in a variety of ways. In this example, you'll use JDBC templates.
If Spring offered nothing more than a little configuration, a smattering of user interface development, and a slightly different programming model, then this book would be done, but Spring offers much more, including tremendous advantages over roll-your-own JDBC:
Resource management
Spring will open and close connections for you, so you won't have to write that tedious code, and you won't have leaks.
Unchecked exceptions
Spring will not force you to use checked exceptions, so you won't have to make those tedious checks for errors that you can't recover from anyway. Instead, you can catch the right exception at the right level.
Inversion of control
Spring will iterate your result set for you, saving effort and keeping your approach consistent.
Configuration
Spring will let you configure and exchange out resources like data sources and connections, without changing code.
In short, you'll write less code, and build programs that are easier to maintain and read. You'll let Spring, instead of tedious, handwritten code do the heavy lifting.
Spring uses a concept called templates. You'll pass each template an SQL query, and a method that will process each row in a result set. Normally, that code, in an inner class, will map the results from a query onto objects. Spring will do the rest.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Refactoring Out Common Code
If you're paying attention, you've probably noticed a little repetition. In fact, some of those inner classes may be better served by separate classes that can populate your domain model. In this example, you'll refactor a little of that common code.
Your small objects may keep this book short, but they're not particularly realistic. Business objects typically have many more fields. If you try to do everything in line, you can accumulate a little too much replication. I like repetition about as much as I like paddling on flat water. In fact, my worst injuries have both come on easier rapids, or easy trails, because I wasn't not paying attention as closely as I should have been. You're likely to find the same phenomenon with tedious, repetitive code: the monotony can keep you from paying attention, and cause an uncomfortable number of minor injuries.
You're simply going to break some of the code in those inner classes free, so they're easier to read and easier to reuse. You'll focus on the code that populates each object (Example 4-8).
Example 4-8. JDBCRentABike.java
public List getBikes( ) {
   final ArrayList results = new ArrayList( );
   JdbcTemplate template = new JdbcTemplate( );

   class BikesHandler implements RowCallbackHandler {
      public void processRow(ResultSet rs) throws SQLException {
         Bike bike = new Bike(rs.getString(MANUFACTURER), 
            rs.getString(MODEL), rs.getInt(FRAME), rs.getString(SERIALNO), 
            rs.getDouble(WEIGHT), rs.getString(STATUS));
         results.add(bike);
      }
   }
      template.query("SELECT * FROM bikes", new BikesHandler( ));
      return results;
   }

   public Bike getBike(String serialNo) {
      final Bike bike = new Bike( );
      JdbcTemplate template = new JdbcTemplate( );
      class BikeHandler implements RowCallbackHandler {
         public void processRow(ResultSet rs) throws SQLException {
            bike.setManufacturer(rs.getString(MANUFACTURER));
            bike.setModel(rs.getString(MODEL));
            bike.setFrame(rs.getInt(FRAME));
            bike.setSerialNo(rs.getString(SERIALNO));
            bike.setWeight(rs.getDouble(WEIGHT));
            bike.setStatus(rs.getString(STATUS));
         }
      }

      template.query("SELECT * FROM bikes WHERE bikes.serialNo = '" 
         + serialNo + "'", new BikeHandler( ));

      return bike;
   }
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using Access Objects
In this example, you're going to take a simple query object and wrap it up in a reusable form. Spring provides an API called RDBMS operational objects to help you wrap stored procedures, queries, and updates.
You may find that you're repetitively defining a block of SQL or a stored procedure. Wrapping it up into a reusable form adds convenience and clarity to your code. Plus, you'll create a thread-safe, reusable form.
In this case, you'll use this feature to look for reservations. To do so, create a new MappingSqlQuery class for each kind of reservation search. Specify parameters for each of the parameters of the query, and then set the types for each of the parameters. As before, you'll specify a method to map each row, with an inner class. Example 4-9 shows the code we have so far.
Example 4-9. JDBCRentABike.java
abstract class FindReservations extends MappingSqlQuery {
   protected List reservations = new ArrayList( );
   protected FindReservations(DataSource dataSource, String query) {
      super(dataSource, query);
   }

   protected Object mapRow(ResultSet rs, int rownum) 
      throws SQLException {
      int resId = rs.getInt(1);
      int bikeId = rs.getInt(2);
      int custId = rs.getInt(3);
      Date resDate = rs.getDate(4);

      Bike bike = getBike(bikeId);
      Customer customer = getCustomer(custId);
      Reservation reservation = new Reservation(resId, bike, 
         customer, resDate);
      reservations.add(reservation);
      return reservation;
   }

   abstract List findReservations(int param);
}

class FindReservationsByCustomer extends FindReservations {
   public FindReservationsByCustomer(DataSource dataSource) {
      super(dataSource, 
         "SELECT * FROM reservations WHERE custId = ?");
      declareParameter(new SqlParameter(Types.INTEGER)); 
      compile( );
   }

   public List findReservations(int param) {
      execute(param);
      return this.reservations;
   }
}

class FindReservationsByBike extends FindReservations {
   public FindReservationsByBike(DataSource dataSource) {
      super(dataSource, 
         "SELECT * FROM reservations WHERE bikeId = ?");
      declareParameter(new SqlParameter(Types.INTEGER));
      compile( );
   }

   public List findReservations(int param) {
      execute(param);
      return reservations;
   }
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Running a Test with EasyMock
It's time to run a test case. Since you're testing a JDBC application, it makes sense for us to verify that it's been used correctly.
Let's say that you wanted to test a single turn signal, one time. One way would be to stand behind the car, and then have someone inside activate the signal. If it didn't blink, then you'd say so. But say that you wanted to test the device before you put it into a car. One strategy would be to plug in a volt meter, a device that measures electricity, instead of a light bulb. Then, if the signal did not generate the right amount of electricity at the right time, the test would fail.
That's how a mock object works. Sometimes, instead of simulating the real world (like our stub in Chapter 1 that simulated a database), you want to know how your object under test is using its interfaces. You might use a mock object instead of a JDBC interface to make sure that the application opens the connection and closes it, just as you expect.
You'll first need to install EasyMock. Download the latest version from http://www.easymock.org and place the easymock.jar file in your project's classpath. We've added it to our /lib folder.
Next, you can establish the collection of mock objects you'll need (Example 4-13). You are effectively drilling down through the JDBC interfaces, and it turns out you will use four of them.
Example 4-13. ControllerTest.java
public void testGetBikesWithMocks( ) throws Exception {
   DataSource mockDataSource;
   Connection mockConnection;
   Statement mockStatement;
   ResultSet mockRS;

   MockControl controlDataSource = 
      MockControl.createControl(DataSource.class);
   MockControl controlConnection = 
      MockControl.createNiceControl(Connection.class);
   MockControl controlStatement = 
      MockControl.createControl(Statement.class);
   MockControl controlRS = 
      MockControl.createControl(ResultSet.class);
         mockDataSource = (DataSource)controlDataSource.getMock( );
         mockConnection = (Connection)controlConnection.getMock( );
         mockStatement = (Statement)controlStatement.getMock( );
         mockRS = (ResultSet)controlRS.getMock( );
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 5: OR Persistence
Near where I live, there's a notorious mountain biking trail with a hill called Beer Mountain. I have no idea how it got its name, because you've got to be stone-cold sober to even contemplate going down. As far as I know, it's never been cleanly climbed (or climbed without stepping off of the bike). Most think it's ridiculous to even try. The hill is long and has an insanely steep gradient. It's covered with loose rock and lots of ledges. I must be too bored with the rest of my life, because I've been working to climb that hill for two and a half years. A hill like that one looks to me like a difficult programming problem. I have started over many times, trying different approaches to the many ledges and boulder gardens on the way to the top. To climb Beer Mountain, I needed to improve my bike, my technique, and my conditioning.
In a fiasco that's become famous, a sample application from Sun was used as a centerpiece for a benchmark in a widely publicized competition between J2EE and .NET. The .NET version soundly beat the EJB-based J2EE version, and the heat was on. Clinton Begin built a simplified version of PetStore around his persistence framework called iBATIS, and it's grown in popularity ever since. Spring provides excellent iBATIS integration, and we'll look at it in this chapter.
Not all problems are well-suited for full-blown persistence frameworks. They're moderately complicated in the best of circumstances. Without the right skills or with an inappropriate problem, they can be disastrous. In a class that we teach together, Ted Neward, the author of Effective Enterprise Java, often compares building or adopting a persistence framework to the United States war in Vietnam, claiming that they're both seductive wars to enter, but both wars are difficult to win, and there's no effective exit strategy in either case. You can still find the blog at http://www.neward.net.
While I won't go quite that far, it's nice to have a framework like iBATIS SqlMaps that gives you a taste of an OR usage model without forcing you to eat a whole elephant with one bite. Specifically, iBATIS lets you:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Integrating iBATIS
In a fiasco that's become famous, a sample application from Sun was used as a centerpiece for a benchmark in a widely publicized competition between J2EE and .NET. The .NET version soundly beat the EJB-based J2EE version, and the heat was on. Clinton Begin built a simplified version of PetStore around his persistence framework called iBATIS, and it's grown in popularity ever since. Spring provides excellent iBATIS integration, and we'll look at it in this chapter.
Not all problems are well-suited for full-blown persistence frameworks. They're moderately complicated in the best of circumstances. Without the right skills or with an inappropriate problem, they can be disastrous. In a class that we teach together, Ted Neward, the author of Effective Enterprise Java, often compares building or adopting a persistence framework to the United States war in Vietnam, claiming that they're both seductive wars to enter, but both wars are