the spring framework · java ee: the good, the bad, and the ugly • java ee establishes a division...

244
The Spring Framework Will Provost Version 2.0.1

Upload: others

Post on 21-Sep-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring

Framework

Will Provost

Version 2.0.1

Page 2: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

ii

117B. The Spring Framework Version 2.0.1 Information in this document is subject to change without notice. Companies, names and data used in examples herein are fictitious unless otherwise noted. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of the author. A publication of Capstone Courseware, LLC. 877-227-2477 www.capstonecourseware.com © 2006-2007 Will Provost. All rights reserved. Published in the United States. This book is printed on 100% recycled paper.

Page 3: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

iii

Course Overview

Chapter 1 Overview of Spring Chapter 2 Core Techniques Chapter 3 Dependency Injection Chapter 4 Validation Chapter 5 The Web Module Chapter 6 The Persistence Tier

Appendix A Learning Resources

Page 4: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

iv

Prerequisites

• This course is intended for experienced Java programmers.

− Lab exercises will require facility with Java coding, building, testing, and debugging.

− A strong comprehension of Java’s object-oriented features will be essential to understanding how Spring manages beans and achieves its high degree of decoupling.

− Spring also makes liberal use of advanced features including Reflection and JavaBeans introspection.

• Basic understanding of XML syntax and grammar will be important, since Spring makes such heavy use of XML to declare beans and collaborations between them.

Page 5: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

v

Labs

• The course relies on hands-on experience in various topics and techniques.

• All lab code is 100% Pure Java, written to build and run on the Java Standard Edition JDK, version 5.0.

• Labs for this course have been installed to the hard drive on each student machine.

• Lab files will be usually be found under:

− c:/Capstone for Windows systems

− $HOME/Capstone for Linux systems

• This is Capstone Courseware’s root directory, shared by this course along with others from the Capstone curriculum.

• In some cases your instructor may have chosen a different root location.

Page 6: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

vi

Directory Structure for the Course

• The course will install to a combination of this shared course root and its own module root directory c:/Capstone/Spring.

− Under this root, the Examples directory holds code examples, including all the starting, intermediate and answer versions of all the labs.

− The Demos directory is home to files that relate to in-class demonstrations. Demonstrations creating files from scratch should also use this directory.

− The Labs directory holds one subdirectory for each lab in the course, named for the lab number. This is where you will do the bulk of your lab work, with some reference to code in the Examples directory.

− The Ant directory holds common build files for web projects.

• Throughout the rest of this student guide, we will refer to directories by relative paths from the module root, as in:

− Examples/Ellipsoid/Beans/Step2

− Demos/Instantiate

− Labs/Lab3A

Page 7: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

vii

Table of Contents

Chapter 1. Overview of Spring ................................................................ 1 Java EE: The Good, The Bad, and the Ugly..........................................................................3 Enter the Framework ..............................................................................................................6 The Spring Framework...........................................................................................................7 Value Proposition....................................................................................................................8 Top-Level Architecture ..........................................................................................................9 Environment and Setup....................................................................................................... 10 Course Exercises: Structure and Usage.............................................................................. 11 Controlling Object Creation: The Core Module .............................................................. 13 Example: A Standalone Spring Application...................................................................... 14 Web Applications: The Web Module ................................................................................ 16 Example: A Spring Web Application................................................................................. 18 Persistence: The DAO and ORM Modules ....................................................................... 25 The Aspect-Oriented Programming Module ................................................................... 26 Integrating Other Frameworks........................................................................................... 27

Page 8: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

viii

Chapter 2. Core Techniques .................................................................. 29 JavaBeans – Origins ............................................................................................................. 31 JavaBeans, Reconsidered ..................................................................................................... 32 The Factory Patterns............................................................................................................ 33 Inversion of Control ............................................................................................................ 34 More XML, Less Java ........................................................................................................... 35 XML View of Spring Beans ................................................................................................. 36 XML Tools............................................................................................................................. 38 Java View of Spring Beans................................................................................................... 39 The XmlBeanFactory Class ................................................................................................. 40 Demo: Declaring and Using Beans .................................................................................... 41 Singleton Beans..................................................................................................................... 44 Singleton vs. Prototype ........................................................................................................ 45 Demo: Declaring and Using Beans .................................................................................... 46 Example: Singleton vs. Singleton........................................................................................ 49 Initializing Bean Properties................................................................................................. 52 Lab2A: Spring Beans from Scratch .................................................................................... 54 Constructor-Argument Matching...................................................................................... 55 Example: Initialization Tactics ........................................................................................... 56 Factory Beans and Methods................................................................................................ 59 Demo: Using Factories ........................................................................................................ 60 Lab2B: Configuring XML Parsers ..................................................................................... 64 Lab2C: Transformation Chains.......................................................................................... 65

Chapter 3. Dependency Injection ......................................................... 77 Complex Systems ................................................................................................................. 79 Assembling Object Graphs.................................................................................................. 80 Dependency Injection.......................................................................................................... 81 Example: Wiring Inputs and Outputs ............................................................................... 82 ref vs. idref............................................................................................................................. 83 Compound Property Names............................................................................................... 84 Inner Beans ........................................................................................................................... 85 Example: Simplifying the Transformer ............................................................................. 86 Example: Content Management......................................................................................... 87 Lab3A: Transformation Chains.......................................................................................... 89 Collections and Maps .......................................................................................................... 90 Populating Maps................................................................................................................... 91 Support for Generics............................................................................................................ 92 Example: Declaring and Using Collections....................................................................... 93 Demo: A New Policy Language .......................................................................................... 95 The Spring Utility Schema ................................................................................................ 100

Page 9: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

ix

Example: Sharing Information ......................................................................................... 101 Lab3B: The Firing Sequence ............................................................................................. 105 Autowiring .......................................................................................................................... 106 Example: Autowiring ......................................................................................................... 107 Aliases .................................................................................................................................. 108 Lab3C: Wholesale Beans.................................................................................................... 109 Order of Instantiation........................................................................................................ 110 Controlling Instantiation Timing .................................................................................... 111 Demo: Lazy Instantiation .................................................................................................. 112

Chapter 4. Validation...........................................................................129 We All Seek Validation...................................................................................................... 131 Spring Validation ............................................................................................................... 132 The Validator and Errors Interfaces ................................................................................ 133 The ValidationUtils Class.................................................................................................. 134 Context for the Errors Object ........................................................................................... 135 Example: An Ellipsoid Validator...................................................................................... 136 The MessageSource Interface ........................................................................................... 137 Deriving a MessageSource ................................................................................................ 138 Putting Validators to Work............................................................................................... 139 Example: Validating Ellipsoids......................................................................................... 140 Lab4A: Single-Order Validation....................................................................................... 142 Nesting Validators.............................................................................................................. 143 Nested Property Paths ....................................................................................................... 144 Lab4B: Wholesale Validation............................................................................................ 145

Chapter 5. The Web Module ................................................................153 Servlets and JSPs: What’s Missing? .................................................................................. 155 The Model/View/Controller Pattern ............................................................................... 156 The Front Controller Pattern............................................................................................ 157 The DispatcherServlet Class.............................................................................................. 158 A Spring Request/Response Cycle ................................................................................... 159 The Strategy Pattern........................................................................................................... 160 JavaBeans as Web Components ....................................................................................... 161 Configuring DispatcherServlet ......................................................................................... 162 Web Application Contexts................................................................................................ 163 Demo: A Minimal Spring Web Application ................................................................... 164 Autowiring in the DispatcherServlet ............................................................................... 174 The HandlerMapping Interface........................................................................................ 175 The Controller Interface.................................................................................................... 176 Controller Responsibilities................................................................................................ 177 The ModelAndView Class ................................................................................................ 178

Page 10: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

x

The View Interface ............................................................................................................. 179 The ViewResolver Interface .............................................................................................. 180 Example: Online Banking.................................................................................................. 181 Lab5A: Wholesale Spring .................................................................................................. 187 Lab5B: Integrating XSLT................................................................................................... 188

Chapter 6. The Persistence Tier...........................................................197 The Data Access Object Pattern ....................................................................................... 199 Spring DAO Implementations ......................................................................................... 201 The DaoSupport Hierarchy............................................................................................... 202 The DataAccessException Hierarchy .............................................................................. 203 JDBC DAOs ........................................................................................................................ 204 The JdbcTemplate Class .................................................................................................... 205 The RowMapper Interface ................................................................................................ 206 MySQL................................................................................................................................. 207 Example: A Wholesale Database ...................................................................................... 208 Lab6: Integrating the Wholesale Database...................................................................... 214 Object/Relational Mapping............................................................................................... 215 Hibernate............................................................................................................................. 216 Hibernate DAOs................................................................................................................. 217 Transaction Control in J2EE............................................................................................. 218 Spring’s Transaction Management .................................................................................. 219 Declarative Transactions ................................................................................................... 220 Spring AOP vs. Annotations............................................................................................. 221 The @Transactional Annotation...................................................................................... 222 Demo: Enforcing Transactions......................................................................................... 223

Appendix A. Learning Resources ........................................................231

Page 11: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

CHAPTER 1

OVERVIEW OF SPRING

Page 12: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

2

OBJECTIVES

After completing “Overview of Spring,” you will be able to:

• Explain the value of the J2EE architecture, but also its limitations.

• Identify major application frameworks for Java.

• Describe the high-level architecture of the Spring application framework

Page 13: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

3

Java EE: The Good, The Bad, and the Ugly

• The Java 2 Platform, Enterprise Edition, or J2EE, was devised as a means of building enterprise-class applications using Java.

• J2EE standards define the connectivity between Java components and non-Java externalities such as the World Wide Web, databases, message queues, and software written in other programming languages.

• For it’s 5.0 release, the platform underwent a shift in naming

convention, dropping the increasingly confusing ‘2’ and giving us either “Java EE” or “JEE” followed by a version number.

Message Queue

Web Server

Web Browser

CORBA Objects

CORBA Objects

CORBA Objects

DCOM Objects

DCOM Objects

DCOM Objects

RDBMS

Web Services

EJBs

Servlets, JSPs

Java Objects

SOAP JDBC

JMS

RMI/IIOP or SOAP

SQL

HTTP

Page 14: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

4

Java EE: The Good, The Bad, and the Ugly

• Java EE establishes a division of labor between containers and components; this is different for web components, vs. EJBs, vs. other component types, but there are some consistent patterns.

• The component-based architecture allows the application

developer to focus on his or her specific problem domain.

− This lowers the cost of development and maintenance of enterprise applications.

• It also allows containers, and the servers that implement them, to offer many enterprise-class features for free:

− Remote connectivity

− Scalability through pooling of objects and threads

− Availability through clustering

− Security and transaction control through declarative means

J2EE Server Web Container Client

Container

Application Servlet

EJB Container

Session Bean

Entity Bean JSP

Page 15: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

5

Java EE: The Good, The Bad, and the Ugly

• Developers have found JEE development a difficult experience.

• To get all the lovely enterprise features, the developer must learn a complex model of component/container interactions.

• There are various constraints on development, which can seem onerous.

− Specific method signatures

− Duplicate development, such as creating interfaces and implementing classes, or even implementing the same method differently in two different classes

− Required base classes for the component that can prevent it from inheriting a more useful, application-specific class

− Complex and burdensome exception-handling practices

• The development process can be heavyweight, with various steps beyond simply compiling classes and installing them.

• At the same time, there are some missing pieces – especially for implementing web applications.

− Servlets and JSPs each serve a useful function, but coordinating request flow and information management between them is essentially left as a problem for the developer.

Page 16: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

6

Enter the Framework

• The Java development community has embraced Java EE, but also responded to its limitations, largely by developing frameworks.

− Ideally, a framework will let the programmer derive the benefits of Java, while reducing the workload and offering additional features.

• Most frameworks are open-source projects of one stripe or

another. Some of the most popular are:

− Struts, still probably the leading web-application framework at the time of this writing

− Tapestry, a web page-building framework

− Hibernate, which focuses on persistence of Java objects to databases through object/relational mapping.

− Cocoon, a content-management framework

− Velocity, an alternative to JSP for defining web presentation

− Tiles, a JSP-friendly means of decomposing pages into reusable parts

Application

Framework

Java EE

Java

Page 17: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

7

The Spring Framework

• The Spring Framework has been gaining traction steadily over the last few years, and seems poised to displace Struts as the web framework of choice.

− Find Spring downloads, news, and related information at http://www.springframework.org

• Spring is more than a web framework, too.

− It offers facilities for persistence, transaction management, messaging (JMS), mail, connectors (JCA), managed beans (JMX), remoting, naming, scheduling, and more.

− It is in fact a mammoth structure of code – consider the following (highly unscientific) size comparison:

Page 18: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

8

Value Proposition

• So, what are we getting for all that weight?

• Spring proposes to simplify and improve J2EE development, in a few key ways:

− It provides a lightweight container for ordinary JavaBeans that allows complex graphs of objects and their relationships to be declared rather than managed programmatically. Spring folks like to call this inversion of control and dependency injection.

− It offers a flexible web framework that implements the model/view/controller pattern and offers pluggable strategies for all of its high-level decision-making.

− It simplifies exception handling by a combination of strategies: minimizing the use of checked exceptions, and providing an excellent error reporting framework.

− It recognizes validation as a fundamental behavior, integrated with general error handling, and easy to integrate into web applications while not being tied specifically to HTTP requests.

− It implements aspect-oriented programming at many levels, allowing “cross-cutting concerns” to be addressed effectively for even very complex applications.

− It offers a simple means of integrating persistence tools while preserving application-level control of transactions.

Page 19: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

9

Top-Level Architecture

• Spring is complex enough, by itself, that to keep it manageable its authors have broken it into six major modules.

− Frankly, the actual code organization defies any easy partitioning.

− Six is as good a number as any; only recently, the same Spring documents that say six today stated that there were seven modules.

• This is the modular structure as envisioned by Spring’s authors:

− The Core module implements the inversion-of-control, or IoC,

container, and implements dependency injection.

− The AOP module provides aspect-oriented-programming facilities to all the other modules.

− The DAO (data-access object) and ORM (object/relational mapping) modules offer various solutions for object persistence, from simple JDBC to more ambitious tools such as Hibernate.

− The Web module is the largest, and provides support for web applications and also integration points for other web frameworks.

− The Java EE module includes Spring’s support for non-web technology such as JavaMail, EJBs, JMS, and JMX.

• This course focuses on the Core and Web modules, with a lighter treatment of DAO and ORM toward the end.

Core

AOP

DAO ORM

Java EE

Web

Page 20: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

10

Environment and Setup

• Hands-on exercises in this course follow a few simple patterns.

• Check now to be sure that your system is set up to support the build-and-test structure for these projects.

• You should have an environment variable CC_MODULE, defined to be the root of the lab software installation.

− This is typically c:\Capstone\Spring.

• The standalone applications built in Chapters 2 and 3 require only this environment variable, and a functional Java 5.0 DK.

− The JDK’s bin directory must be on the executable path.

• The web applications developed later in the course require additional tools. These are bundled with the lab software, and most of the setup is keyed to the CC_MODULE variable.

− The Ant make utility must be on the executable path – this will be %CC_MODULE%\..\Tools\Ant1.6\bin.

− The Tomcat web server/container must be started and stopped.

− Spring itself is deployed automatically by the Ant builds, as part of any given web application.

− A simple set of XML authoring tools is also available – not necessary to build, but often helpful in managing Spring’s XML-based configurations.

• We’ll introduce these tools as needed throughout the course.

Page 21: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

11

Course Exercises: Structure and Usage

• Standalone applications will be built from project workspaces using simple batch scripts.

<root> (e.g. Examples/Bank/Beans/Step1) Accounts.xml build.bat run.bat doc index.html (etc.) src cc bank Account.java CheckingAccount.java Controller.java

− Source code is found under the directory src.

− Javadoc for the prepared source code has been compiled into the directory doc.

− Often there will be an XML file defining the beans to be used for this application.

• build will compile Java classes, and copy other files necessary for the application into a build space.

• run will run the application, sometimes with command-line arguments.

Page 22: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

12

Course Exercises: Structure and Usage

• Web-application projects use Ant, which will carry out a more complex set of tasks.

<root> (e.g. Examples/Ellipsoid/Web/Step5) build.properties build.xml doc (as in standalone projects) docroot index.jsp Results.jsp Sphere.jsp classes tags WEB-INF Ellipsoid-servlet.xml web.xml src cc math Ellipsoid.java EllipsoidController.java

− In addition to the src directory, these projects include a docroot directory that holds web files such as HTML pages, JSPs, the web.xml deployment descriptor, supporting JARs, and tag files.

− There will often be supporting data files as well.

• Build and deploy to Tomcat with a simple command: ant.

Page 23: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

13

Controlling Object Creation: The Core Module

• Spring’s Core module allows you to declare to the IoC container any number of JavaBeans that you want to be available at runtime.

• This allows many, even most, of the classes used in an application to be written without explicit code dependencies on one another.

− It is a general best practice in Java to define an interface to desired behavior and an implementation of that behavior.

− This language feature makes it possible to decouple implementations, because each relies only on the other’s interface.

− Spring’s IoC container makes it practical to do this, by eliminating the last barrier to it, which was the need to state the implementation class in the code of the dependent class for purposes of instantiating the object.

• This offers a modest benefit for a single object, or a flat layer of independent objects.

• Its value increases rapidly as a target system becomes more interdependent; each new object-to-object relationship is easily managed in configuration files, and individual classes don’t need to be constantly recoded to reflect changing dependencies.

Page 24: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

14

A Standalone Spring Application

• In Examples/Bank/Beans/Step1 is a very simple example of Spring IoC: two bank accounts, each of a different Java class.

• The objects are configured in Accounts.xml: <beans ... > <bean id="Account" class="cc.bank.Account" /> <bean id="CheckingAccount" class="cc.bank.CheckingAccount" /> </beans>

• The main application, Controller.java, loads and exercises each of the beans:

Resource configFile = new FileSystemResource ("Accounts.xml"); BeanFactory factory = new XmlBeanFactory (configFile); Account smith = (Account) factory.getBean ("Account"); exercise (smith);

EXAMPLE

Page 25: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

15

A Standalone Spring Application

• This really is a trivial example, but this basic idea of declaring object instantiation, rather than coding it, is powerful.

− Add to this the ability to wire one object to another, ad infinitum, and you have a great foundation for the more sophisticated systems that live elsewhere in Spring.

• This also gives us an opportunity to test the basic configuration of classroom machines, and to start to get familiar with the layout of the course’s hands-on exercises. Build and test the application now, as shown below:

build run (Various Spring logging output here ...) Creating new account for Mr. Smith ... Type is cc.bank.Account Starting balance is $ 100.00 After deposit, balance is $ 150.00 After withdrawal, balance is $ 100.00 Creating new account for Mr. Jones ...

• We’ll return in full force to the Core module in Chapters 2 and 3.

EXAMPLE

Page 26: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

16

Web Applications: The Web Module

• Spring addresses the problem of implementing web functionality in Java by several strategies, the most important of which is the model/view/controller pattern, or MVC.

• For web applications, MVC calls for components to play distinct roles and to collaborate in handling an HTTP request.

− A controller is the component most directly responsible for

carrying out the requested work: adding a record to a database, fetching the results of a query, etc.

− It relies on the model for all application state – persistent data, transient objects in memory, session state, etc.

− It ultimately forwards control to a view, which is responsible for presenting results to the user in the form of a web page.

• An MVC-oriented web application may have a distinct controller and view for each different request URI.

− Or, there may be some overlapping, but the M/V/C roles are not monolithic; there will be many instances of each.

Controller View

Model

Page 27: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

17

Web Applications: The Web Module

• Spring implements web MVC, and provides plug-in points for a variety of roles that are separated more finely than just M, V, and C: handler mappings, view resolvers, interceptors, and more.

• All of these actors in the web application are JavaBeans – and so Spring web applications live in Spring IoC containers.

− The Web module defines specialized containers and factories known as web contexts.

− The bean definitions – analogous to our Accounts.xml earlier – are deployed in the WEB-INF directory, alongside web.xml, and are located by the Spring framework classes when the application is installed on the server.

• Thus for each major role in the application there are options, from simple to sophisticated, and you can build as much or (almost) as little of the infrastructure as you want to.

Page 28: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

18

A Spring Web Application

• In Examples/LandUse/Step1 there is a Spring application that offers web-hosted management of public land-use proposals.

• We’ll take a much deeper tour of this application in later chapters.

− Also, this example is incomplete! as we’ll be filling in some of the functionality in lab exercises.

• But let’s look at the basic layout and function now.

• As with any web application, it’s best to start our tour with the deployment descriptor: see docroot/WEB-INF/web.xml.

<servlet> <servlet-name>LandUse</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>LandUse</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

− This maps all requests ending in .do to a single, “master” servlet, which is Spring’s DispatcherServlet.

− What will it do with those requests?

EXAMPLE

Page 29: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

19

A Spring Web Application

• DispatcherServlet uses certain naming and typing conventions to seek out delegate objects in a Spring beans configuration file.

− See docroot/WEB-INF/LandUse-servlet.xml.

• Several top-level objects are defined here; the first one that will be involved with an incoming HTTP request is the handler mapping:

<bean class="org.springframework.web.servlet.handler .BeanNameUrlHandlerMapping" />

− This class defines the web application’s strategy for dispatching incoming requests to specific controllers – in this case matching the request URL to a bean name elsewhere in the configuration.

− (Get used to the long package and class names, by the way. Spring’s authors don’t ever seem to have met a name token they didn’t like!)

EXAMPLE

Page 30: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

20

A Spring Web Application

• There are several controllers defined. Most of the action in this version of the application happens as a result of requests to proposals.do, and this is mapped to a “multi-action controller:”

<bean name="/proposals.do" class="gov.usda.usfs.landuse.web .MultiActionController" > <property name="delegate" ref="proposalController" />

− This specific controller implementation does additional dispatching, to different methods on a delegate object based on the name of a request parameter that is assumed to match the submit button that was clicked:

<property name="methodNameResolver" > <bean class="org.springframework.web.servlet.mvc .multiaction.ParameterMethodNameResolver" > <property name="methodParamNames" > <list> <value>add</value> <value>edit</value> <value>remove</value> </list> </property> </bean> </property> </bean>

EXAMPLE

Page 31: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

21

A Spring Web Application

• When a controller is done with its work, it returns its directions for how to respond to the user.

• It does this by triggering the loading and rendering of a view, and most often this will require the help of a view resolver:

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

− This particular resolver maps view names as provided by the controller – for instance “detail” – to actual page-generating resources, adding prefix and suffix to get the path to the resource – such as detail.jsp.

EXAMPLE

Page 32: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

22

A Spring Web Application

• Let’s build and test this application, to get a better sense of how these things fit together.

• Start the Tomcat server now – we’ll talk about this more in a later chapter, but essentially you just need to run the following script from its own home directory:

%CC_MODULE%/../Tools/Tomcat5.5/bin/startup

− You’ll see a new console appear for the newly-started server process, and after a few seconds Tomcat will be initialized, showing a confirmation like this:

INFO: Server startup in 6229 ms

• Now, from the example directory itself (Examples/LandUse/Step1), run Ant to build and deploy:

ant (lots of tracing here) deploy: [echo] Deploying LandUse to Tomcat ... all: BUILD SUCCESSFUL Total time: 2 seconds

− Tomcat picks up hot-deployed applications on a 30-second timer, so after a moment you will see it install the LandUse application.

INFO: Servlet 'LandUse' configured successfully

EXAMPLE

Page 33: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

23

A Spring Web Application

• Visit the running application in your web browser: http://localhost:8080/LandUse

− So far, we haven’t invoked Spring – this is just a plain old JSP.

EXAMPLE

Page 34: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

24

A Spring Web Application

• Choose a proposal and click Edit – this will trigger a request to proposals.do with a request parameter called “edit”, and that in turn will invoke a specific controller that serves up a specific view.

• We won’t get any deeper into the workings of the application

until we’re ready to study the Spring Web module in depth – which begins in Chapter 4.

− Try clicking a few other buttons and links, but you’ll eventually see that there are several missing pieces.

EXAMPLE

Page 35: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

25

Persistence: The DAO and ORM Modules

• Spring does not attempt to implement a persistence framework.

• It does however complement other persistence frameworks and technologies very well.

− Spring’s Core module provides an excellent means of establishing declarative control over objects in those frameworks, and of keeping location specifics like database URLs and user credentials out of the Java code.

− Spring’s approach to exception handling is especially potent when dealing with persistence frameworks – many of which are burdened with heavy use of checked exceptions and otherwise require a great deal of repetitive “catch and throw” coding.

• Spring also offers a nice lightweight framework for managing database transactions.

− The theory here is that if EJB containers can provide declarative transaction control to session and entity beans, why shouldn’t plain old Java objects enjoy the same features?

− With really just one simplifying assumption – a single database, i.e. no distributed transaction support – Spring is able to deliver those features to its managed JavaBeans.

Page 36: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

26

The Aspect-Oriented Programming Module

• Spring does a nice job, across the board, of implementing features in the right places: vertical features in specific subclasses, horizontal features in top-level handlers.

• Sometimes a feature is generic, and yet it should happen transparently – not by way of an explicit call to a reusable method, but without the target class’ direct involvement.

• In the Spring Web module, since there’s a cycle of request handling in action, it’s possible to get a lot of this via interceptors.

• For the general case, though, we’re talking about aspect-oriented programming, and those “generic” or “horizontal” features are what AOP calls cross-cutting concerns.

• Spring’s AOP module provides a framework for identifying, declaring, and implementing cross-cutting concerns.

• It is a tricky little library, and it is also likely to gradually give way to Java’s own AOP feature set, which begins in Java 5 with the annotation.

− We’ll also see that Spring AOP introduces some memory-management problems having to do with repeated code generation.

Page 37: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

27

Integrating Other Frameworks

• Spring is perhaps just as popular as an integration tool as it is for its own frameworks and utilities.

• The Core module offers an elegant means of declaring, configuring, and assembling objects, and this makes it a surprisingly useful tool for connecting the singletons that tend to be the cornerstones of other frameworks.

• Spring’s Web module is so flexible and customizable that it will play nicely with most any of the popular web frameworks out there, such that you can mix and match subsystems.

− Again, one of the key tools here is the Spring interceptor.

− This allows any number of common tasks to be carried out before a request is “handled” by a specific controller.

− This then is a perfect place to consult a different framework’s MVC mappings, apply its input-validation tools, and so forth.

• Spring even includes packages of code just for the purpose of integrating certain other frameworks with its own Web module.

Page 38: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 1

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

28

SUMMARY

• Spring’s essential take on Java EE is, “Yes, it’s good; but no, it’s not good enough!”

• The Core module brings many features associated with Java EE to any Java SE application.

• The Web module certainly embraces the servlets, JSP, JSTL, and JSF specifications – all Java EE technology – and then builds a more complete and sophisticated system on top of them.

• Its relationship to EJB is much more frosty – Spring is all about providing lightweight support for enterprise features, where EJB is perceived as unduly heavy.

• Then there are many other Java EE standards that Spring uses, but enhances, much like its approach to web applications:

− JMS, JavaMail, JDBC, JMX, JCA ... and the list of things that start with ‘J’ goes on and on.

• Spring does load up on the code, the packages, the classes, the import statements, but they’ve done so many things so well that it’s worth the overhead to get Spring involved in an application development effort.

• Spring also boasts excellent support for unit testing – another win for the lightweight container and for Spring’s meticulous observance of interface/implementation splits.

Page 39: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

CHAPTER 2

CORE TECHNIQUES

Page 40: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

30

OBJECTIVES

After completing “Core Techniques,” you will be able to:

• Explain the concepts of inversion of control and dependency injection, and their value to Java applications.

• Declare JavaBeans for an application for loading by a Spring IoC container, and instantiate those beans using a bean factory.

• Explain the difference between singleton and prototype scopes, and use each correctly in an application.

• Populate Spring beans by declaring property values in the Spring IoC configuration.

Page 41: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

31

JavaBeans – Origins

• The JavaBeans specification originally came out in 1997.

• It defined a component model for Java that was, at the time, meant to rival Visual Basic’s VBXs and ActiveX controls.

− Components had properties, methods, and events, each of which to different degrees could be automatically wired to other beans or configured by an interactive user/designer.

− Rapid-application-development (RAD) tools and GUI builders could interact with libraries of JavaBeans to make application design a largely visual and interactive process.

• Most of this specification has either found its (GUI-based) niche or faded from common practice.

• Meanwhile, Java EE has defined increasingly complex structures for enterprise component types.

• One of these, of course, has a clear JavaBeans heritage: EJB, after all, stands for Enterprise JavaBeans.

− There was the sense in the invention of EJB that this was taking simple components or “beans” and souping them up so that they could participate in large-scale, distributed systems.

Page 42: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

32

JavaBeans, Reconsidered

• Relative to this history, Spring is, in a way, taking a step back and choosing another path.

− It rejects the weight and design constraints of EJB.

− But it embraces JavaBeans proper, perhaps more than EJB itself does, more than many Java technologies do.

• The one piece of the original JavaBeans specification that has really resonated throughout Java is the idea of a bean property.

− A property is not just a field, though it is often backed by a field.

− It is one or both of a pair of methods of a conventional signature, for a property name with a specific Java type:

public type getName (); public void setName (type newValue);

• Properties make beans automatable.

− RAD tools can configure them easily.

− JSP expression language, and other scripting languages, can read trees of beans through a simple dot notation – the “address” of a piece of information is a simple string, and not necessarily a fragment of Java code.

• Spring recognizes that beans could play a much larger role in general application development – if they had a little push in a new direction ...

Page 43: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

33

The Factory Patterns

• For non-GUI applications, the biggest barrier to more complete automation of bean-to-bean interactions has been the need for one object to create another object explicitly, as in

HelperClass helper = new HelperClass ("module", 2);

− This innocuous bit of code indicates a subtle problem: every class that creates an object develops a code-level dependency on that object’s class.

− Extrapolated to a complex application, this gets in the way of decoupling, resulting instead in highly interdependent systems, which then are harder to maintain or reconfigure.

• Several closely-related design patterns define means of isolating the capability to create a certain object or family of objects – shown below is the Abstract Factory UML:

− Factories are the basic tools with which developers can get free of

interdependencies, making their applications more flexible for future requirements or on-site reconfiguration.

Page 44: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

34

Inversion of Control

• Spring’s inversion of control can be seen as a complete generalization of the factory approach.

− An IoC container is a general-purpose factory.

− It can make that object available to other objects by name, not by its concrete Java type.

− It can create any type of Java object, given the right configuration.

• “Inversion of control” and “dependency injection” essentially mean that the beans themselves do not control their initial state or their dependencies to other beans.

− There is always some master controller that kicks off the process.

− But for the most part, beans are ignorant of the concrete types of their collaborators; and this is appropriate, as they should only care about the abstract types.

IoC Container

Object A

Object B Object C

Controller

Bean Factory

Page 45: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

35

More XML, Less Java

• Like many other web-development platforms and Java EE standards, Spring makes heavy use of XML.

• This establishes a declarative alternative to the more traditional programmatic means of implementing a given feature.

− Instead of coding the feature in Java, one declares the feature to the Spring IoC container.

• Declarative development is quicker and more productive, and it lets a generic piece of software – such as a server or container – carry out boilerplate tasks for a specific piece of software, which is your application.

• Also, changes can be implemented "live" without recompiling Java classes.

• Spring is unlike most other frameworks in that its declarative vocabulary is mostly limited to the very generic language of JavaBeans: this object ID, that class, this property name, that value or dependency to another object.

• So the specific meanings of declarations will vary with the beans that are using them; some examples that we’ll encounter in the Web module are:

− Mapping request URI to controller and view components

− Mapping request parameters to JavaBean properties

− Assigning validators to business or command objects

− Transaction attributes

Page 46: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

36

XML View of Spring Beans

• Most Spring applications use a standard XML vocabulary for configuring their IoC containers – though there are alternatives.

• The schema for this is found in the Spring distribution – it’s on your machine now at

%CC_MODULE%/../Tools/Spring2.0/dist/resources /spring-beans-2.0.xsd

• A configuration file has a root element <beans>, which has any number of <bean> definitions.

Page 47: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

37

XML View of Spring Beans

<bean id="MySpecialBean" class="com.mycompany.MyClass" > <property name="x" value="5" /> <property name="delegate" ref="OtherBean" /> </bean>

• A <bean> then has attributes, which can include

− id for reference by a factory or other beans

− name, for the same purpose – but where an id has to be a legal XML name, name (and this may be a little backwards) doesn’t

− class, which is its Java type

− factory-bean and factory-method to inform the container of an abstract factory that can create this bean

• It can have child elements which further define it; the most important of these are

− property, which is the primary means of providing initial state to the bean – including simple values like numbers and strings but also dependencies to other beans

− constructor-arg, which is much like property but connects to constructor arguments instead of JavaBeans “setters” and so requires some different configuration

Page 48: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

38

XML Tools

• To support XML authoring in the classroom, a few simple tools have been included with the course software.

• One is the Crimson text editor – run this from %CC_MODULE%/../Tools/Crimson3.70/cedit.exe

− You might also create a desktop shortcut to this file, or associate it with text and XML files on your system.

• Another is the XML Validator, which will

− parse an XML file for well-formedness

− validate a file for correctness against an XML Schema

• Crimson has been primed with hotkeys that link to these two functions, so that if you edit Spring configurations in Crimson, you can press F9 to parse the file or F10 to validate it against spring-beans-2.0.xsd.

− Beware that either of these actions will save the file to disk before running the command – usually a good thing.

• When working through the exercises in this and the next few chapters, you may find that frequently validating with F10 will help you catch small syntax and grammar errors as you work.

Page 49: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

39

Java View of Spring Beans

• Having declared one or more beans to the IoC container, you can instantiate the container and ask it to configure the beans for you.

• BeanFactory is the representative of an IoC container.

• Instantiate one of the many bean factory subtypes as appropriate for the context of your application.

− For this and the next chapter, we’ll rely on XmlBeanFactory for our standalone applications.

− After that we’ll be implicitly using an XmlWebApplicationContext when a DispatcherServlet loads our controllers, command objects, and other beans.

− Spring is a bit package-crazy, as we’ve seen. Rather than laying out

every package for every class we discuss, we’ll call out important packages here and there.

− See the quick reference at the end of the book for an index of classes and packages.

Page 50: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

40

The XmlBeanFactory Class

public interface BeanFactory { public Object getBean (String); public Object getBean (String, Class); public boolean containsBean (String); public boolean isSingleton (String); public Class getType (String); public String[] getAliases (String); } public class XmlBeanFactory (indirectly) implements BeanFactory { public XmlBeanFactory (Resource); public XmlBeanFactory (Resource, BeanFactory); }

• Create an XmlBeanFactory to represent your beans configuration by supplying it with a Resource representing the configuration file.

− A Resource is a Spring abstraction of file, URL, or other stream-producing entity.

− We’ll consider these in more depth later, but for our purposes now they are essentially wrappers around files.

Resource config = new FileSystemResource ("MyCfg.xml"); BeanFactory factory = new XmlBeanFactory (config);

Page 51: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

41

Declaring and Using Beans

• We’ll work a little more with basic bean declaration and usage in this demonstration – picking up where we left off with the simple beans example from the previous chapter.

− We’ll work in Demos/Instantiate.

− The completed demo is in Examples/Bank/Beans/Step4.

1. Review the Accounts.xml configuration – the two Java classes are the classic bank-account inheritance example, with the CheckingAccount imposing a transaction fee by overriding a method from the base class Account.

<beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi="..." xsi:schemaLocation="..." > <bean id="Account" class="cc.bank.Account" /> <bean id="CheckingAccount" class="cc.bank.CheckingAccount" /> </beans>

DEMO

Page 52: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

42

Declaring and Using Beans

2. In src/Controller.java, see that the main method uses a bean factory to create instances of these beans, and passes each through a test method exercise.

Resource configFile = new FileSystemResource ("Accounts.xml"); BeanFactory factory = new XmlBeanFactory (configFile); Account smith = (Account) factory.getBean ("Account"); exercise (smith); ... 3. Build and run the application, and observe the results: Creating new account for Mr. Smith ... Type is cc.bank.Account Starting balance is $ 100.00 After deposit, balance is $ 150.00 After withdrawal, balance is $ 100.00 Creating new account for Mr. Jones ... Type is cc.bank.CheckingAccount Starting balance is $ 100.00 After deposit, balance is $ 148.50 After withdrawal, balance is $ 97.00 Creating new account for Ms. Black ... Ms. Black's balance is $ 97.00 Mr. Jones's balance is $ 97.00 Ms. Black makes a deposit ... Ms. Black's balance is $ 145.50 Mr. Jones's balance is $ 145.50

DEMO

Page 53: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

43

Declaring and Using Beans

4. It’s simple enough to create and use these beans ... but wait a minute. Does something look wrong to you? Why did Mr. Jones’s account fluctuate when Ms. Black opened hers? Why do both accounts change again when Ms. Black makes a deposit?

5. Of course the behavior suggests that somehow we have two references to the same Java object – could this be? Look at the code again:

Account jones = (Account) factory.getBean ("CheckingAccount"); ... Account black = (Account) factory.getBean ("CheckingAccount"); System.out.format ("Ms. Black's balance is ...", black.getBalance ()); System.out.format ("Mr. Jones's balance is ...", jones.getBalance ()); 6. Is BeanFactory.getBean not giving us a new instance each time it’s

called?

DEMO

Page 54: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

44

Singleton Beans

• No, it isn’t.

• By default, Spring beans are considered singletons.

• This isn’t really earth-shaking, but it can be an unpleasant surprise, if you write a lot of code expecting to get multiple instances of each bean.

• This tells us something about the kinds of beans Spring is expecting to create, too.

• Spring is geared towards enterprise applications.

− Certainly it can support J2SE standalone applications as well.

− But enterprise applications tend to require a number of free-standing services: registries, factories, managers, handlers, etc.

− These are almost always best defined as singletons – for performance, for easy access, and for other reasons.

• Most applications also make heavy use of business objects, or data objects, or other classes that are meant to exist in multiple instances in memory.

− Spring is not primarily intended to support these.

− Ultimately there’s not much of a use case for this anyway: would you want the state of each data object recorded in a Spring beans configuration?

− No. Rather, you would declare the factory for a certain data type in Spring, and let that class manage the incarnation of the data.

Page 55: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

45

Singleton vs. Prototype

• If you do want multiple instances of a Spring bean, you can have them; you just need to tell the container what you want.

− Declare this to the container by declaring scope=“prototype” on the bean.

• Now the container will indeed start farming out a fresh instance of your bean on each new request.

• Note, too, that you can have multiple instances of a class by declaring multiple Spring <bean>s of that class – each with a different id or name attribute.

− That is, the container enforces singleton behavior for each declared bean; it is not tied to the Java type.

− Indeed, it is considered a significant win for Spring that you get singleton behavior for free, without having to code the usual private constructor and factory method called for by the Singleton design pattern.

Page 56: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

46

Declaring and Using Beans

• Let’s pick up with our demonstration now, and experiment with singletons and prototypes.

7. Try declaring that both beans are prototypes, not singletons: <bean id="Account" class="cc.bank.Account" scope="prototype" /> <bean id="CheckingAccount" class="cc.bank.CheckingAccount" scope="prototype" /> 8. Run the application again. (By the way, not to put too fine a point on

it, but of course you don’t need to rebuild the application – this is a small example of how declarative development allows easy reconfiguration at runtime, even in a production environment.)

run Creating new account for Ms. Black ... Ms. Black's balance is $ 100.00 Mr. Jones's balance is $ 97.00 Ms. Black makes a deposit ... Ms. Black's balance is $ 148.50 Mr. Jones's balance is $ 97.00 9. That’s got it. Now, what if we wanted to establish distinct names and

starting states for each of the three beans that we actually create?

DEMO

Page 57: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

47

Declaring and Using Beans

10. Change the IDs of the beans to the names of the account holders, and create a third bean declaration for Ms. Black:

<bean id="Smith" class="cc.bank.Account" scope="prototype" /> <bean id="Jones" class="cc.bank.CheckingAccount" scope="prototype" /> <bean id="Black" class="cc.bank.CheckingAccount" scope="prototype" /> 11. Because you’ve changed the bean names, you’ll have to change the

Java code to get beans with those names: Account smith = (Account) factory.getBean ("Smith"); etc. 12. Now you will have to rebuild. You should see the same behavior as

with the last test.

13. Now, and we’re looking ahead a little bit here, declare the initial balance of each bank account, using a constructor argument:

<bean id="Smith" class="cc.bank.Account" scope="prototype" > <constructor-arg type="double" value="2000" /> </bean> etc.

DEMO

Page 58: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

48

Declaring and Using Beans

14. Test again and see that you can control the initial state from outside the compiled application:

Creating new account for Mr. Smith ... Type is cc.bank.Account Starting balance is $ 2,000.00 After deposit, balance is $ 2,050.00 After withdrawal, balance is $ 2,000.00 Creating new account for Mr. Jones ... Type is cc.bank.CheckingAccount Starting balance is $ 5,000.00 After deposit, balance is $ 5,050.00 After withdrawal, balance is $ 5,000.00 Creating new account for Ms. Black ... Ms. Black's balance is $10,000.00 Mr. Jones's balance is $ 5,000.00 Ms. Black makes a deposit ... Ms. Black's balance is $10,050.00 Mr. Jones's balance is $ 5,000.00 15. Finally, remove the scope attributes that you added earlier. Again,

the singleton behavior attaches to the declared bean, not to the class, and so we can declare three singleton beans of two distinct classes and know that we will have exactly three instances in memory at runtime. Test again and see identical results.

DEMO

Page 59: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

49

Singleton vs. Singleton

• So Spring has a singleton and Java has a singleton. Wonder what would happen if they ever had a fight?

• In Examples/Singleton is another experiment, applying singleton and prototype declarations to a Java class that already implements the Singleton design pattern by itself.

− See src/cc/Registry.java: public class Registry extends HashMap<String,Object> { private Registry () {} private static final Registry INSTANCE = new Registry (); public static Registry getInstance () { return INSTANCE; } }

− ... and Objects.xml: <bean id="Registry" class="cc.Registry" scope="prototype" />

EXAMPLE

Page 60: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

50

Singleton vs. Singleton

• A Java class then tries to create multiple instances of the Registry class, using a bean factory – see src/Controller.java.

public static void main (String[] args) { ... Registry reg1 = (Registry) factory.getBean ("Registry"); Registry reg2 = (Registry) factory.getBean ("Registry"); reg1.put ("Name1", "Value1"); reg2.put ("Name2", "Value2"); System.out.println (reg1); }

− If we have a true singleton on our hands, then reg1 will hold both keys, since reg2 will refer to the same object.

− If it’s a prototype, each registry will hold just one mapping.

• Okay – what do you think will happen?

EXAMPLE

Page 61: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

51

Singleton vs. Singleton

• Try it out: build run {Name1=Value1}

• It’s a prototype!

• How is this possible? Doesn’t the Java Singleton implementation look pretty air-tight?

• Dig into this far enough – which we won’t do here – and you’ll find out that Spring is using some quite advanced code to enforce either a singleton or a prototype behavior.

− It uses Java Reflection to find constructors and to “make them accessible” – meaning it can bypass the private modifier on the constructor of Registry and create the object directly!

− This may be a troubling discovery. Spring is, arguably, breaking the rules of Java, and of object-oriented visibility attributes.

− Or we can see it as more a re-invention than a transgression, and clearly if Spring IoC is going to work, it’s necessary to have consistent behavior over any sort of Java class.

− However you score it, note that this technique also raises some security concerns. If you run Spring in a process with a Java security manager, you may have to grant certain permissions to the spring.jar for IoC to function correctly.

EXAMPLE

Page 62: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

52

Initializing Bean Properties

• To provide initial state to a Spring bean, use one of two techniques, depending on the public interface of the bean itself.

− To invoke a JavaBeans mutator method (a more precise term for “setter”), declare a <property> for the bean.

Page 63: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

53

Initializing Bean Properties

• As you can see, there are a lot of options from here.

• Actually most of these are prescribed by the type of the JavaBeans property you’re setting, but there are some alternatives, too.

• For a simple value, just define property name and value: <property name="index" value="2" />

− You can use a child element for this, instead: <property name="index" > <value>2</value> </property>

• We’ll look at most of the other options in the following chapter.

Page 64: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

54

Spring Beans from Scratch

Suggested time: 30 minutes

In this lab you will build a simple Java application that uses instances of the Ellipsoid class – a JavaBean which encapsulates the geometry of a three-dimensional ellipsoid using read/write properties a, b, and c for the dimensions and read-only properties volume, type, and description calculated from these:

Your application will use Spring to decouple itself from the particulars of what objects are created and how they are populated. You’ll build most of the Java application, and create the configuration file from scratch; the target class and some build-and-test infrastructure is already in place.

Detailed instructions are found at the end of the chapter.

Ellipsoid

a b c

ab c volume type description

LAB 2A

Page 65: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

55

Constructor-Argument Matching

• To pass arguments to the constructor of a bean, use the <constructor-arg> element.

• This has much the same syntax as <property>, but because constructor arguments are matched ordinally, rather than by name, there are different options.

• The Spring documentation requires the following:

− For each argument, set the index attribute to a zero-based ordinal identifying the constructor parameter for which you’re providing a value.

− Where there is only one parameter, or the types of the parameters are all distinct, you can leave out the index and Spring will match arguments by a given type attribute instead.

− To disambiguate between overloaded constructors, you must specify both index and type.

• In practice, however, the index attribute is not strictly necessary; the container will take arguments in their stated order.

− type is still important to resolve overloads.

Page 66: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

56

Initialization Tactics

• Examples/Initialize shows the range of possible approaches – see Objects.xml.

• For the BankAccount type, whose constructor takes a string and a number, we get away without index attributes:

public BankAccount (String holder, double balance); <bean id="Bank" class="cc.BankAccount" > <constructor-arg value="Mr. Jones" /> <constructor-arg value="10000" /> </bean>

− Switch the order of the arguments, and get a parsing exception.

• UserAccount’s constructor takes two strings – still no problem:

public UserAccount (String user, String password); <bean id="User" class="cc.UserAccount" > <constructor-arg value="wprovost" /> <constructor-arg value="boondoggle" /> </bean>

− Switch the arguments and get no exception, but probably bad data!

EXAMPLE

Page 67: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

57

Initialization Tactics

• Finally, we declare beans of type Connection, which has overloaded constructors:

public Connection (String address); public Connection (String address, int retries); public Connection (String address, String Mode); public Connection (String address, String mode, int retries);

− We see two attempts to instantiate this class as Spring beans: <bean id="Connection1" class="cc.Connection" > <constructor-arg value="143.199.24.12" /> <constructor-arg value="half-duplex" /> </bean> <bean id="Connection2" class="cc.Connection" > <constructor-arg value="143.199.24.12" /> <constructor-arg value="3" /> </bean>

− Here we’ll see there’s a problem.

EXAMPLE

Page 68: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

58

Initialization Tactics

• Build and test: build run BankAccount: Mr. Jones, balance is $10,000.00 UserAccount: name is wprovost Connection: 143.199.24.12, half-duplex, 0 retries. Connection: 143.199.24.12, 3, 0 retries.

• That last object isn’t what we wanted.

− We wanted the “3” to be interpreted as an integer, invoking the two-argument constructor that takes a string and an int.

− A Java compiler could have figured this out, but once those quotes go around it, the integer 3 looks like any other string to the Spring IoC container, and it misreads our intentions. Silly container.

• Clean this up with a type attribute: <bean id="Connection2" class="cc.Connection" > <constructor-arg value="143.199.24.12" /> <constructor-arg type="int" value="3" /> </bean> run BankAccount: Mr. Jones, balance is $10,000.00 UserAccount: name is wprovost Connection: 143.199.24.12, half-duplex, 0 retries. Connection: 143.199.24.12, duplex, 3 retries.

EXAMPLE

Page 69: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

59

Factory Beans and Methods

• We’ve seen that Spring sort of butts heads with Java when it comes to who gets to enforce singularity.

• By contrast, it’s quite friendly to existing factories.

• Call a factory method instead of a constructor by identifying the method name with the factory-method attribute.

− The <constructor-arg> child element is overloaded to supply arguments to a factory method instead of a constructor.

<bean id="aClass" class="java.lang.Class" factory-method="forName" > <constructor-arg value="com.myCompany.MyClass" /> </bean>

• Identify a separate factory class using both factory-bean and factory-method.

<bean id="aPackage" class="java.lang.Package" factory-bean="aClass" factory-method="getPackage" />

Page 70: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

60

Using Factories

• We’ll work through a demonstration now of using factories in declared beans.

• In Demos/Factories, the Bank example has been extended to include an abstract factory Manager and a default implementation class:

− We’ll rearrange our configuration to take advantage of this new system.

− The completed demo is found in Examples/Bank/Beans/Step6.

1. Start by building and running the example as before ... but with a very different outcome:

build run Creating new account for Mr. Smith ... Exception in thread "main" ... 1 constructor arguments specified but no matching constructor found in bean 'Smith' ...

DEMO

Page 71: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

61

Using Factories

2. What has changed? Look at either of the target bean classes and see that their constructors have been made unavailable to the Spring IoC container.

− From src/cc/bank/Account.java – the constructor is visible only within its own package:

Account (double balance) { this.balance = balance; } 3. Look at src/cc/bank/Manager.java, and see that we have a true

abstract factory – one that sports a factory method of its own and supports “plug-in” replacements via system properties:

public static Manager getInstance () throws InstantiationException, ClassNotFoundException, IllegalAccessException { String className = System.getProperty ("cc.bank.Manager.class", "cc.bank.DefaultManager"); Class managerClass = Class.forName (className); return (Manager) managerClass.newInstance (); } public abstract Account openAccount (double initialBalance); public abstract CheckingAccount openCheckingAccount (double initialBalance);

− cc.bank.DefaultManager implements the two abstract methods, simply creating new objects using the initialBalance argument.

DEMO

Page 72: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

62

Using Factories

4. Open Accounts.xml and modify the way in which we create bank accounts. First, create a factory bean:

<bean id="manager" class="cc.bank.Manager" factory-method="getInstance" /> 5. Now use this factory to create the three accounts we want: <bean id="Smith" class="cc.bank.Account" factory-bean="manager" factory-method="openAccount" > <constructor-arg type="double" value="200" /> </bean> <bean id="Jones" class="cc.bank.Account" factory-bean="manager" factory-method="openCheckingAccount" > <constructor-arg type="double" value="500" /> </bean> <bean id="Black" class="cc.bank.Account" factory-bean="manager" factory-method="openCheckingAccount" > <constructor-arg type="double" value="1000" /> </bean>

DEMO

Page 73: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

63

Using Factories

6. Build and re-test, and you’ll see correct behavior. build run Creating new account for Mr. Smith ... Type is cc.bank.Account Starting balance is $ 200.00 After deposit, balance is $ 250.00 After withdrawal, balance is $ 200.00 Creating new account for Mr. Jones ... Type is cc.bank.CheckingAccount Starting balance is $ 500.00 After deposit, balance is $ 548.50 After withdrawal, balance is $ 497.00 Creating new account for Ms. Black ... Ms. Black's balance is $ 1,000.00 Mr. Jones's balance is $ 497.00 Ms. Black makes a deposit ... Ms. Black's balance is $ 1,050.00 Mr. Jones's balance is $ 497.00

− Notice that the correct type of object is created according to the choice of factory method, createAccount or createCheckingAccount.

− You could remove the class attributes from the <bean> declarations entirely, with no adverse effects.

− We’re no longer relying on that attribute for the runtime type of the object.

DEMO

Page 74: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

64

Configuring XML Parsers

Suggested time: 30 minutes

In this lab you will experiment with using Spring beans and factories to configure an XML parser for an application that wants to read and/or validate some XML files. Here, your target beans are actually classes from the Java standard API – specifically the JAXP SAXParser and SAXParserFactory types. JAXP implements a classic abstract-factory pattern, and so you’ll be able to refactor some existing Java code to use Spring beans. You will also see, at the end of the lab that there are limits to what Spring can interpret when working with methods that don’t strictly adhere to JavaBeans conventions.

Detailed instructions are found at the end of the chapter.

LAB 2B

Optional

Page 75: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

65

Transformation Chains

Suggested time: 30 minutes

In this lab you will use Spring IoC to configure an XSLT transformation, using the JAXP Transformer and related types as defined in the javax.xml.transform package:

You will refactor existing code. Here we don’t have the barrier that we encountered with XML parsers – the need to call a method between instantiating the factory bean and instantiating the target bean. So you’ll be able to do more of the work declaratively.

Detailed instructions are found at the end of the chapter.

LAB 2C

Page 76: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

66

SUMMARY

• We’ve now got a pretty good handle on creating individual objects using the Spring IoC container.

− We control the name and type of the object.

− We can populate its properties with values or pass arguments to its constructor(s).

− We can use factory methods and separate factory classes.

• It’s a fair amount of new syntax to learn – especially to do something you were already able to do in Java!

• But hopefully the value of this facility is evident, especially for more complex applications.

• The final lab exercise hints at the features we have yet to study – the full capacity for what Spring calls dependency injection, and from that the ability to conjure whole trees or webs of objects that can serve our application code.

Page 77: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

67

Spring Beans from Scratch

In this lab you will build a simple Java application that uses instances of the Ellipsoid class – a JavaBean which encapsulates the geometry of a three-dimensional ellipsoid using read/write properties a, b, and c for the dimensions and read-only properties volume, type, and description calculated from these:

Your application will use Spring to decouple itself from the particulars of what objects are created and how they are populated. You’ll build most of the Java application, and create the configuration file from scratch; the target class and some build-and-test infrastructure is already in place.

Lab workspace: Labs/Lab2A

Backup of starter code: Examples/Ellipsoid/Beans/Step1

Answer folder(s): Examples/Ellipsoid/Beans/Step2

Files: src/cc/math/Ellipsoid.java src/Controller.java Ellipsoids.xml (to be created)

Instructions:

1. Review the source code for the target JavaBean in src/cc/math/Ellipsoid.java. As you can see, the diagram above summarizes its behavior.

2. src/Controller.java already has a helper method reportOn which is able to produce a formatted report on a given Ellipsoid instance. Create a main method as well.

3. Initialize a Resource called configFile to a new FileSystemResource – pass “Ellipsoids.xml” to the constructor. This is the name of the bean-configuration file that we’ll create later in the lab.

4. Initialize a BeanFactory called factory to a new XmlBeanFactory based on your configFile.

Ellipsoid

a b c

ab c volume type description

LAB 2A

Page 78: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

68

Spring Beans from Scratch LAB 2A

5. Now call getBean on that factory, and pass the first command-line argument as the bean name. This will allow you to test different bean configurations easily.

6. Pass the resulting bean to reportOn – you’ll have to downcast it to type Ellipsoid.

7. Run build from the command line at this point to check your coding so far. (If you didn’t do it yourself already, or have an IDE do it for you, the compiler will now insist that you import the various Spring types you’ve used in the main method.)

8. Create the file Ellipsoids.xml, and use one of our earlier examples as a template so you don’t have to type out all those namespace URIs and schema locations. You should now have a configuration file with a <beans> root element but no other content.

(By the way, you will find that you have to have all of the namespace and schema-location content that we’ve been seeing in other examples. The namespace declaration is essential, so that all the contents of this file are correctly understood as being part of the Spring beans vocabulary and not some other model. The xsi:schemaLocation attribute is another story. According to the XML Schema specification, this should be entirely optional. But the XmlBeanFactory class will fail to load the file if this isn’t defined. In the author’s humble opinion, this is a Spring bug.)

9. Declare a bean of type Ellipsoid (use the full name including the package) and an id of “boring”.

10. Give your bean three property values: a=3, b=4, c=5.

11. You can now test the system as follows: run boring Three-dimensional ellipsoid -- properties: Semi-axis A: 3.0 Semi-axis B: 4.0 Semi-axis C: 5.0 Volume: 251.32741228718342 Type: Triaxial ellipsoid Definition: Where none of A, B and C are equal; the most general classification of an ellipsoid. 12. Define two more beans “intriguing” and “cool”. The first can have values a=4, b=4,

c=5; and the second will have all values set to 4.

Page 79: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

69

Spring Beans from Scratch LAB 2A

13. Test your two new beans: run intriguing Three-dimensional ellipsoid -- properties: Semi-axis A: 4.0 Semi-axis B: 4.0 Semi-axis C: 5.0 Volume: 335.1032163829113 Type: Prolate spheroid Definition: An "elongated" ellipsoid with a single axis of symmetric rotation that is longer than the other two axes (which are equal). run cool Three-dimensional ellipsoid -- properties: Semi-axis A: 4.0 Semi-axis B: 4.0 Semi-axis C: 4.0 Volume: 268.082573106329 Type: Sphere Definition: Where A = B = C, offering perfect rotational symmetry in all three dimensions. 14. Try one last bean, called “default”, and don’t define any properties at all, as in: <bean id="default" class="cc.math.Ellipsoid" /> 15. Test that one – so the cool bean is not so very cool afer all ... run default Three-dimensional ellipsoid -- properties: Semi-axis A: 1.0 Semi-axis B: 1.0 Semi-axis C: 1.0 Volume: 4.1887902047863905 Type: Sphere Definition: Where A = B = C, offering perfect rotational symmetry in all three dimensions.

The idea of course is that if we don’t define any properties in our configuration, we’ll just get the default values (if any) as defined by the Java class.

Page 80: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

70

Configuring XML Parsers

In this lab you will experiment with using Spring beans and factories to configure an XML parser for an application that wants to read and/or validate some XML files. Here, your target beans are actually classes from the Java standard API – specifically the JAXP SAXParser and SAXParserFactory types. JAXP implements a classic abstract-factory pattern, and so you’ll be able to refactor some existing Java code to use Spring beans. You will also see, at the end of the lab that there are limits to what Spring can interpret when working with methods that don’t strictly adhere to JavaBeans conventions.

You’ll see that the primary bean in this exercise, cc.tools.xml.SAXValidator, wraps those two JAXP classes to provide a simplified means of parsing and validating XML documents:

Lab workspace: Labs/Lab2B

Backup of starter code: Examples/Parsers/Step1

Answer folder(s): Examples/Parsers/Step2 (intermediate) Examples/Parsers/Step3 (final) Examples/Parsers/Step4 (an unsuccessful experiment)

Files: src/cc/tools/xml/SAXValidator.java src/Controller.java XML.xml

LAB 2B

Optional

Page 81: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

71

Configuring XML Parsers LAB 2B

Instructions:

1. Review the source code for the SAXValidator class, and see that it implements the SAX DefaultHandler interface to trap warning, error, and fatalError events during XML parsing. If you are not familiar with JAXP parsing, you might want to review the Java API documentation on this, focusing on packages org.xml.sax and javax.xml.parsers. But basically this class is configured to receive parsing events so that it can produce error messages to the console.

The method of greatest interest for this exercise is getSchemaValidatingSAXParser, which uses SAXParserFactory to instantiate itself and then instantiate a SAXParser. Before creating the parser, it sets switches to assure that parsers it creates will validate documents that they parse, and that they will treat documents as being namespace-aware.

2. Build and test the starting system, to get a feel for the baseline behavior: build run Valid.xml run Invalid.xml Error at Line 8: cvc-complex-type.2.4.a: Invalid content was found starting with element 'Make'. One of '{"":Car, "":Part}' is expected. ...

So, no news is good news on Valid.xml, and errors reported on Invalid.xml are dumped to the console. You’ll now progressively refactor this code to maximize the use of the Spring IoC container.

3. Open src/Controller.java, and replace the call to create a new SAXValidator with use of an XmlBeanFactory, as we’ve done in other exercises so far: import the right types; read in the configuration file; create a factory object, and call getBean on that factory. Assume a bean name of “Validator”; you’ll configure this in a moment.

4. Open the beans config file, XML.xml. Declare your “Validator” bean.

5. Build and re-test, and you should have consistent behavior. (This is the intermediate answer in Step2.)

6. Now play the same trick in SAXValidator itself: in getSchemaValidatingSAXParser, use an XmlBeanFactory and that same configuration file to replace the call SAXParserFactory.newInstance. This bean will be named “ParserFactory.”

7. Configure the “ParserFactory” bean in XML.xml, using “newInstance” as the factory-method.

8. Test again and see that the application still works as before.

Page 82: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

72

Configuring XML Parsers LAB 2B

9. You’ve probably noticed that you’re in a good position to convert more Java code to XML configuration: the call to setValidating right after the parser factory is created is easily replaced with a <property> definition. Make that change and re-test. (This is the final answer in Step3.)

Optional Steps

10. Could you pull off the hat trick and configure the parser itself, using the parser-factory bean and Spring’s factory- bean and factory-method attributes? Give it a try: declare a third bean called “Parser” using “ParserFactory” as the factory bean and “newSAXParser” as the factory method.

11. Change the Java code so that it doesn’t explicitly get involved in creating the factory object at all; it just asks Spring for a SAXParser by getting the “Parser” bean from the factory:

SAXParserFactory factory = (SAXParserFactory) beanFactory.getBean ("ParserFactory"); factory.setFeature ("http://xml.org/sax/features/namespaces", true); result = (SAXParser) beanFactory.getBean ("Parser"); 12. Test it out – bit of a problem here: build run Valid.xml Error at Line 6: cvc-elt.1: Cannot find the declaration of element 'Dealership'. 13. We’ve tried for a bridge too far: Spring was able to carry out our various creation and

configuration requirements up to a point, but it has no way to replace the call to setFeature that you just removed from the Java code. If there were a property namespaceAware on the parser factory, we could set it to true; but Spring can’t intuit that this method setFeature that takes a name and a value might be a property setting. So in this conversion, we lose that setting, and the fact that the parser is not expecting namespace-aware documents throws off its behavior. (This is the final version of the exercise, in Step4.)

Page 83: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

73

Transformation Chains

In this lab you will use Spring IoC to configure an XSLT transformation, using the JAXP Transformer and related types as defined in the javax.xml.transform package:

You will refactor existing code. Here we don’t have the barrier that we encountered with XML parsers – the need to call a method between instantiating the factory bean and instantiating the target bean. So you’ll be able to do more of the work declaratively.

Lab workspace: Labs/Lab2C

Backup of starter code: Examples/Transformer/Step1

Answer folder(s): Examples/Transformer/Step2 (intermediate) Examples/Transformer/Step3 (final)

Files: TransformerObjects.xml (to be created) src/Controller.java

Instructions:

1. Build and run the starter application, which takes three arguments on the command line: source XML document, XSLT transform, and output filename. (Below we use the special device name con to pipe transform output right to the console; you can provide a filename here, too.)

build run Source.xml Transform.xsl con This is the result I wanted! 2. Open Controller.java, and refactor the code in the main method to use a bean

factory loaded from a file “TransformerObjects.xml” (which you’ll create in a moment), and get a bean named “Transformer”. You’ll need to import several Spring types, as in our earlier exercises. Build and check your code for compile errors.

LAB 2C

Page 84: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

74

Transformation Chains LAB 2C

3. Now create the configuration file, with the usual shell of a <beans> element, which you can copy in from any of this chapter’s exercises.

4. Declare a <bean> called “XFormFactory” of class javax.xml.transform.TransformerFactory. This bean must be created using the factory method newInstance.

5. Now declare your “Transformer” bean: the class is javax.xml.transform.Transformer, and you’ll use the factory method newTransformer on the “XFormFactory” bean.

6. Validate your file and run the application again. If you’ve coded everything as directed so far, you’ll encounter an odd result at this point:

run Source.xml Transform.xsl con <?xml version="1.0" encoding="UTF-8"?><Root> <Detritus>Some junk I don't need</Detritus> <Useful>This is the result I wanted!</Useful> <Flotsam> <Jetsam size="5"/> Mixed-content junk down here. </Flotsam> </Root>

This is (ahem) not the result we wanted. Did you notice what was lost in the transition to using XmlBeanFactory?

7. Originally we passed the second command-line argument as the filename from which to load a transform. Now we’re ignoring that argument – you could pass any value at all instead of “Transform.xsl” there – and in the configuration file we’re not supplying any value. The only reason we didn’t get an exception here is that there are overloads of the factory method. The overload that takes no parameters creates an “identity transformer” – one that is useful in JAXP for piping information between different representations, as in a DOM tree to a character stream. That’s why we get the whole Source.xml as our output.

8. Enhance your declaration of the “Transformer” bean by defining a third bean, “Transform”. This will be of type javax.xml.transform.stream.StreamSource, and it needs its own constructor argument, which will be the name of the transform file.

Page 85: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 2

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

75

Transformation Chains LAB 2C

9. Now declare a reference to that bean as an argument to the factory method for the “Transformer”. We’re jumping ahead a little here, because we don’t cover bean references until the next chapter. But the syntax is simple and the meaning should be obvious:

<bean id="Transformer" class="javax.xml.transform.Transformer" factory-bean="XFormFactory" factory-method="newTransformer" > <constructor-arg ref="Transform" /> </bean> 10. Test again, and you should see the old behavior, as you’ve now replaced the old

behavior exactly. (This is the intermediate answer in Step2.) run Source.xml doesn’t-matter con This is the result I wanted! Optional Steps

11. Replace the first and third command-line arguments as well, by declaring additional beans for source and result filenames. One of these will be nearly identical to the “Transform” bean, but with the name “Source” and the value “Source.xml”. The other will be of type javax.xml.transform.stream.StreamResult, and have the name “Result” and the value “con” or perhaps “Result.txt”.

12. In Controller.java, rip out the code at the beginning of main that checks for the presence of three command-line arguments.

13. Then replace the references to args[0] and args[2] with calls to the bean factory. Remember to downcast each bean to the appropriate type.

14. You should now be able to run without any arguments: build run This is the result I wanted! 15. Change the name of the transform file in the config, to “LessUseful.xsl”, and run

again: run Some junk I don't need This is the result I wanted! Mixed-content junk down here.

(This is the final answer in Step3.)

Page 86: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,
Page 87: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

CHAPTER 3

DEPENDENCY INJECTION

Page 88: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

78

OBJECTIVES

After completing “Dependency Injection,” you will be able to:

• Assemble graphs of Java objects using dependency injection.

• Use inner beans to simplify declarations of bean relationships.

• Populate bean properties that are collections and maps.

• Take advantage of bean auto-wiring.

• Declare aliases for beans.

• Control the order in which declared beans are instantiated.

Page 89: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

79

Complex Systems

• Complex applications are developed in both Java SE and EE.

• Complexity is not just a matter of size – number of classes, number of objects, lines of code, number of users, etc.

• Complex systems have a number of potentially troubling attributes.

• They are too detailed for any one developer to know them intimately and completely.

− That is, an implementer may know part of the application in great detail, while an analyst may know the whole system at a summary level; but no one person knows the whole system in detail.

• They are deployed unpredictably.

− At least some resources of the production system are in locations not known at development time.

• They often require incremental change that is effected by replacing a subsystem while the system is running.

− Perhaps a server is stopped and re-started, but the point is that some of the deployed code has to make friends with new classes and components, without being recompiled itself.

• All of these attributes argue against system interdependency, and yet it is a basic aspect of the Java language that object creation requires knowledge of the concrete type of the object.

Page 90: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

80

Assembling Object Graphs

• The stated purpose of the Spring IoC container is to “instantiate, configure, and assemble” complex systems.

− We’ve seen how to instantiate: that’s declaring a bean and using a bean factory’s getBean method.

− Configuration is achieved through setting bean properties.

• Assembly means establishing meaningful relationships between instantiated beans – while preserving inversion of control.

• We’d like a solution that can implement relationships like these:

− Simple dependency, sometimes called collaboration: one object

makes use of another, without owning that other object or having any meaningful lifecycle relationship.

− Association and aggregation, both of which imply a deeper connection between the objects, and meaningful lifecycle relationships.

− Relationships with multiple cardinality, such as one-to-many and many-to-many.

Page 91: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

81

Dependency Injection

• Java classes will for the most part define the required relationships of any given class.

• But for inversion of control to be preserved, Spring needs to provide a means of satisfying those requirements.

• Dependency injection is really just an extension of the idea of populating a bean’s properties – but now we’re talking about properties whose types are other JavaBeans.

− So if configuration is supplying single values, assembly is a matter of supplying references to other objects.

• Use the ref attribute on a <property> or a <constructor-arg>, instead of a value, to establish a reference to another declared bean, by name.

<property name="helper" ref="MyDelegateBean" />

− As with value, there is the option to use a child element: <property name="helper" > <ref bean="MyDelegateBean" /> </property>

Page 92: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

82

Wiring Inputs and Outputs

• Examples/Transformer/Step4 shows simple dependency injection for the JAXP Transformer.

• This would not work with the Transformer class itself, because it doesn’t define its source and result objects as properties – only as method parameters, and we can’t script that.

• There is a new class cc.tools.xml.XSLTransformer that wraps the use of a JAXP transformer, and that does provide the necessary properties, with methods setSource and setResult.

• Thus we can declare relationships to the source and result beans directly to the transformer – this is “injecting a dependency.”

<bean id="Transformer" class="cc.tools.xml.XSLTransformer" > <constructor-arg ref="Transform" /> <property name="source" ref="Source" /> <property name="result" ref="Result" /> </bean>

− The bean is unaware of the choice of source and result objects.

− In fact not even the controller, which does know the name of the transformer bean, needs to be concerned about the configuration of that bean to use certain source, transform, and result objects.

EXAMPLE

Page 93: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

83

ref vs. idref

• Another means of identifying a collaborating bean is to state its name as an idref.

− The previous declaration could be rewritten: <bean id="Transformer" class="cc.tools.xml.XSLTransformer" > <constructor-arg idref="Transform" /> <property name="source" idref="Source" /> <property name="result" idref="Result" /> </bean>

• The difference is that in this case, the configured bean is expected to instantiate the collaborating bean by explicitly using the bean factory.

− The mutator method will take a string, not an object reference.

• In that case, why idref; why not just use value?

• By stating that a value is the name of another configured bean, we give the Spring container the opportunity to validate the value.

− An idref value that is not resolved to the ID or name of a declared bean will be flagged as a validity error – perhaps well before there’s any attempt to use the configuration, load the beans, etc.

− An ordinary value, while it would satisfy the type requirements of the constructor or method, would then result in a later failure to instantiate the bean at runtime.

Page 94: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

84

Compound Property Names

• Spring supports compound property names, sometimes called nested properties, via the usual “dot syntax.”

− Technically, nested properties are a related, but different thing.

− We’ll come back to them in a later chapter.

• This is a convention by which a tree of object references can be parsed and addressed.

− If bean A has a property of B which is another bean, and that bean has a property C, then we can reference that property as “A.B.C”.

− Indexed properties are also supported: if property B is an array or list of other things, then “A.B[2]” will get the third such thing; if B is a map, then “A.B[‘key’]” will get the value at the key “key”.

− Compound and indexed properties can be combined ad infinitum: “A.B[2].C[0][D[3]]” is maybe a bit ornate, but it is supported.

• Most scripting languages support this syntax or something very much like it:

− JSP expression language

− JSTL

− JavaScript

• Spring supports this syntax wherever it’s useful, and that includes property names in bean configuration files.

Page 95: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

85

Inner Beans

• It is not necessary to define every bean as a top-level, named entity that can be referenced by other beans.

• The grammar also supports nested definitions of beans to satisfy a single property or constructor argument, and these are known as inner beans.

• These are not to be confused with inner classes; the two may coincide, but they are not really related concepts.

• Inner beans are just a convenience for the configuration author:

<bean id="dependent" class="Dependent" > <property name="helper" > <bean class="Helper" /> </property> </bean>

• Notice that the inner bean doesn’t have an id or name attribute.

− It doesn’t need one, since it can’t be referenced externally anyway.

− It is just there to satisfy a single dependency, and so it is declared inline and (by its lack of a name) privately.

Page 96: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

86

Simplifying the Transformer

• Examples/Transformer/Step5 shows a refactoring of the configuration file to use only inner beans:

<bean id="Transformer" class="cc.tools.xml.XSLTransformer" > <constructor-arg> <bean class= "javax.xml.transform.stream.StreamSource" > <constructor-arg value="Transform.xsl" /> </bean> </constructor-arg> <property name="source" > <bean class= "javax.xml.transform.stream.StreamSource" > <constructor-arg value="Source.xml" /> </bean> </property> <property name="result" > <bean class= "javax.xml.transform.stream.StreamResult" > <constructor-arg value="con" /> </bean> </property> </bean>

EXAMPLE

Page 97: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

87

Content Management

• For the sake of some further exercise in Spring dependency injection, we’re going to take the Transformer application on a great leap forward, and show how it can be the basis for a highly configurable content management system.

• In Examples/Transformer/Step6, the XSLTransformer class has been reworked to carry out XSLT transforms between any combination of paths and pipes, with the help of a new class:

− The Pipe is really just an in-memory parking space for XML content; but what’s critical is that it can serve both as the output receptacle for a transform and the input source for another one:

− This basic interrelationship can be extrapolated to quite complex content-management chains and trees.

Source.xml Filter.xsl Subset

Format2.xsl

Format1.xsl Report1.xml

Report2.xml

Path Transformer Pipe

EXAMPLE

Page 98: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

88

Content Management

• The XSLTransformer has also been made more easily configurable: the sourcePath and resultPath properties are of type String, rather than Source and Result.

− Internally, the class just converts the given file path to a Source or a Result object.

• TransformerObjects.xml has been refactored along with this code change:

<bean id="Transformer" class="cc.tools.xml.XSLTransformer" > <constructor-arg value="Transform.xsl" /> <property name="sourcePath" value="Source.xml" /> <property name="resultPath" value="con" /> </bean>

− It’s worth noting that we’ve boiled this configuration interface down to the bare essentials, but we still have the critical feature of decoupling: the code that uses this transformer is not bound to any of the relevant locations.

− Since the last step we have made the simplifying assumption that the type of sources and results will be StreamSource and StreamResult, respectively – not too great a constraint.

EXAMPLE

Page 99: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

89

Transformation Chains

Suggested time: 30-45 minutes

In this lab you will use a combination of simple property values and injected bean dependencies to configure a complex tree of XML transformations that produces an array of output documents:

Detailed instructions are found at the end of the chapter.

SummaryText.xsl

Summary.txt

Detail.txt

summaryText

detailText

accessible SummaryText

accessible DetailText

Accessible Summary.txt

accessible Units

DetailText.xsl

SummaryText.xsl

DetailText.xsl

Accessible.xsl

Accessible Detail.txt

Statistics.xsl

Statistics.xsl

accessible Statistics

statistics

accessible StatisticsText

Accessible Statistics.txt

StatisticsText.xsl

statisticsTextStatistics.txt

StatisticsText.xsl

Listings.xml

statisticsText

accessible

stats

accessibleStats

LAB 3A

Page 100: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

90

Collections and Maps

• Spring offers declarative support for properties that are collections or maps of values.

• Note that using compound property naming would not work here, because that syntax will never instantiate new objects.

− It assumes that the tree is already constructed and just lacks various leaf values; it assumes that any indexed property has already been allocated or “dimensioned” to its correct size.

− This will be an issue later, when we work with command objects.

• Spring supports various Collections API types, each by its own element name, used as a child of a property, constructor argument, or other collection type:

− <list> populates a List, with child elements <value>, <bean>, <ref>, or another collection type

− <set> populates a Set with the same possible child elements

− <map> populates a Map; this model is a little more complex

− <props> populates a Properties object, much the way a map works but with fewer options

Page 101: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

91

Populating Maps

• The model for the <map> element involves a child element for each <entry>:

− These in turn have keys (either a key attribute or a <key> child

element) and values (any of the usual suspects, as with lists).

• The <props> element can be populated in a similar fashion to a map object, with <prop> children instead of <entry>s.

Page 102: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

92

Support for Generics

• Spring 2.0 has decent support – call it “best-effort” – for Java-5.0 collection types that take advantage of generics.

• We say best-effort because there is a real challenge here:

− Type parameters are erased at runtime – by the time the container and bean factory are in play, their target types are plain old Lists and Maps, even if they were List<String> and Map<Long,Set<String>> when they were compiled.

− It’s not feasible to declare the full generic type of a collection as a class name in the configuration – after all, the angled brackets would be misinterpreted as XML markup!

• There are ways around both of these difficulties, but even in spite of them, Spring will do a pretty good job of recognizing type parameters.

− If you use <list> to populate a List<Integer>, Spring will convert your numeric values to Integer objects – even though at runtime it could get away with piling up String objects that would later get you in trouble.

− There are limits to its powers of perception, though – push it too far, especially with nested collection types, and it will eventually fail to find the right type conversion.

Page 103: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

93

Declaring and Using Collections

• See Examples/Collections/Step1 for a simple example of declaring the contents of collection-type properties.

• The class cc.Holder defines three properties: List<String> names; Map<String,Integer> frequencies; Map<String,Set<String>> errors;

• The configuration file Collections.xml makes short work of this:

<bean id="Holder" class="cc.Holder" > <property name="names" > <list> <value>Sam</value> <value>Fred</value> <value>Jane</value> </list> </property> <property name="frequencies" > <map> <entry key="Rock" value="787" /> <entry key="Paper" value="662" /> <entry key="Scissors" value="1090" /> </map> </property> ...

EXAMPLE

Page 104: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

94

Declaring and Using Collections

− It even handles the nested type, a map of strings and sets of strings: ... <property name="errors" > <map> <entry key="firstName" > <set> <value>Field is required</value> </set> </entry> <entry key="lastName" > <set> <value>Field is required</value> </set> </entry> <entry key="age" > <set> <value>Field is required</value> <value>Must be a positive number</value> </set> </entry> </map> </property> </bean>

• The application does very little, just instantiates the bean and dumps its values to the console:

build run [Sam, Fred, Jane] {Rock=787, Paper=662, Scissors=1090} {firstName=[Field is required], lastName=[Field is required], age=[Field is required, Must be a positive number]}

EXAMPLE

Page 105: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

95

A New Policy Language

• We’ll put our newfound facility with collections to work.

• The Java security architecture specifies a Java-like grammar for policy files:

grant codeBase "file:This.jar" signedBy "Fred" { permission java.io.FilePermission "SomeFile.txt", "read"; permission java.util.PropertyPermission "java.home", "read"; };

• Maybe an XML vocabulary would be better!

• Do your work in Demos/Policy.

− The completed demo is in Examples/Policy/Step2.

1. If you like, review the code in src/cc/security/DynamicPolicy.java. The full implementation of a J2SE Policy is not important, but notice that the behavior of the class is based on a property permissionsMap that is a Map<CodeSource,List<Permission>>.

2. Controller.main sets an instance of this class as the local security policy, installs a security manager, and then attempts to read a system property. Since reading system properties is a checked action, and a security manager is in play, the policy will have to grant permission to the Controller class for this action to succeed.

Policy.setPolicy ((Policy) factory.getBean ("SecurityPolicy")); System.setSecurityManager (new SecurityManager ()); System.out.println ("Property java.home is " + System.getProperty ("java.home"));

DEMO

Page 106: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

96

A New Policy Language

3. Build and test, and observe that the action does fail: build run Exception in thread "main" java.security.AccessControlException: access denied (java.util.PropertyPermission java.home read) 4. If you open Policy.xml, you’ll see why: the policy bean is declared,

but the permissionsMap is not populated, so it sits empty when the access controller checks for the necessary permission.

5. Now we’ll start building up a declaration of a specific security policy. Start by setting the permissionsMap property to a map with one empty entry:

<bean id="SecurityPolicy" class="cc.security.DynamicPolicy" > <property name="permissionsMap" > <map> <entry> </entry> </map> </property> </bean>

DEMO

Page 107: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

97

A New Policy Language

6. Define the key for the entry as a CodeSource object. To create this bean you have to provide constructor arguments: the location of the code source as a string, and the list of parties who’ve digitally signed the code source. This latter argument is null, so we’ll use a construct we haven’t yet studied, but a very simple one: null is <null/>.

<entry> <key> <bean class="java.security.CodeSource" > <constructor-arg value= "file:/C:/Capstone/Spring/Demos /Policy/build/" /> <constructor-arg > <null/> </constructor-arg> </bean> </key> </entry> 7. Grant the necessary permission to this code source, as one element in

a list: </key> <list> <bean class= "java.util.PropertyPermission" > <constructor-arg value="java.home" /> <constructor-arg value="read" /> </bean> </list> </entry>

DEMO

Page 108: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

98

A New Policy Language

8. Test again, and see how your policy declaration flies: run (ouch) (oh, that’s rude) Failed to convert value of type [java.lang.String] to required type [java.security.cert.Certificate[]]; nested exception is java.lang.IllegalArgumentException: No matching editors or conversion strategy found (oops) 9. The bean factory really didn’t like something that we did! The gist of

the error report that we get back is shown above: couldn’t convert a string to an array of certificates ... ?

10. If you look at the constructors for CodeSource, there are two constructor overloads – one of which takes an array of certificates:

javap java.security.CodeSource public class java.security.CodeSource extends java.lang.Object implements java.io.Serializable{ public java.security.CodeSource(java.net.URL, java.security.cert.Certificate[]); public java.security.CodeSource(java.net.URL, java.security.CodeSigner[]); 11. We don’t really care which constructor we call, since we just want to

pass null for either the certificate array or the signer array. But Spring cares! It cares deeply, and it can’t make the decision based on a string value and a null.

DEMO

Page 109: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

99

A New Policy Language

12. You’d figure a type attribute would be the solution here; but, strangely, what works is an index attribute. Set this as shown:

<constructor-arg value= "file:/C:/Capstone/Spring/Demos/Policy/build/" /> <constructor-arg index="1" > <null/> </constructor-arg> 13. Test now, and you should see that the policy is instantiated correctly

– and, what’s more, it works! run Property java.home is c:\Java1.5

DEMO

Page 110: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

100

The Spring Utility Schema

• Spring 2.0 introduces a number of new XML models for content that can appear in a beans configuration file.

• We’ll see models for AOP and transactions later in this course.

• Now, we’ll look at the utility schema, which makes possible a few new configurations:

− Beans that are collections – note that so far we’ve only seen beans that hold collections as properties

− Using a property of one bean to initialize a property on a another

− Gaining access to constants defined on a Java class and treating those values as configurable beans

• A configuration file that uses these new constructs must declare a namespace prefix for this separate schema and identify the schema location:

<beans xmlns="...beans" xmlns:util= "http://www.springframework.org/schema/util" xmlns:xsi="..." xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema /beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema /util/spring-util-2.0.xsd" >

Page 111: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

101

Sharing Information

• What if we wanted to configure a second instance of our three-collection Holder class, and for it to have its own data for one of the collections but the same data for the other two?

− We could just clone the whole bean config and edit from there – a/k/a copy-and-paste “reuse.”

− It would be much better, more maintainable, to define those two shared collections just once each, and then re-use the information.

− We’ll look at two ways of doing that.

• In Examples/Collections/Step2 are two new configuration files.

• SeparateBeans.xml defines each of the three collections (that were inner beans in the “Holder” bean before) as first-class beans of their own, using the utility vocabulary:

<util:list id="globalNames" > <value>Sam</value> <value>Fred</value> <value>Jane</value> </util:list> <util:map id="globalFrequencies" > <entry key="Rock" value="787" /> <entry key="Paper" value="662" /> <entry key="Scissors" value="1090" /> </util:map> <util:map id="globalErrors" > ...

EXAMPLE

Page 112: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

102

Sharing Information

• The utility schema defines <util:list>, <util:set>, and <util:map>.

• Each has the same effect: it defines whichever type of collection object as a named bean, rather than as a property of some other bean, and populates the collection with the same child elements as <list>, <set>, and <map> as shown earlier.

• This makes it possible to configure the “Holder” bean using bean references:

<bean id="Holder" class="cc.Holder" > <property name="names" ref="globalNames" /> <property name="frequencies" ref="globalFrequencies" /> <property name="errors" ref="globalErrors" /> </bean>

− ... and for a second bean “Reuser” to share two of them while defining its own frequencies map:

<bean id="Reuser" class="cc.Holder" > <property name="names" ref="globalNames" /> <property name="frequencies" > <map> <entry key="Heads" value="501" /> <entry key="Tails" value="499" /> </map> </property> <property name="errors" ref="globalErrors" /> </bean>

EXAMPLE

Page 113: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

103

Sharing Information

• Build and test using command-line arguments to identify the configuration file and bean to instantiate and dump:

build run SeparateBeans.xml Holder [Sam, Fred, Jane] {Rock=787, Paper=662, Scissors=1090} {firstName=[Field is required], lastName=[Field is required], age=[Field is required, Must be a positive number]} run SeparateBeans.xml Reuser [Sam, Fred, Jane] {Heads=501, Tails=499} {firstName=[Field is required], lastName=[Field is required], age=[Field is required, Must be a positive number]}

• CrossReference.xml takes a different approach, using the <util:propertyPath> element.

− This uses a compound property expression in its path attribute to find a bean property defined elsewhere in the configuration.

− It then exposes that property as a named bean, which can then be instantiated by the factory, or referenced normally by other beans.

EXAMPLE

Page 114: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

104

Sharing Information

• So, in this file, the “Holder” bean is the same as it was in Step1.

• The two collections we want to share are exposed as beans: <util:property-path id="usefulNames" path="Holder.names" /> <util:property-path id="usefulErrors" path="Holder.errors" />

• The new “Reuser” bean now has something to latch onto using a property reference:

<bean id="Reuser" class="cc.Holder" > <property name="names" ref="usefulNames" /> <property name="frequencies" > <map> <entry key="Heads" value="501" /> <entry key="Tails" value="499" /> </map> </property> <property name="errors" ref="usefulErrors" /> </bean>

• Test this configuration and see we get the same effect: run CrossReference.xml Reuser [Sam, Fred, Jane] {Heads=501, Tails=499} {firstName=[Field is required], lastName=[Field is required], age=[Field is required, Must be a positive number]}

EXAMPLE

Page 115: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

105

The Firing Sequence

Suggested time: 15-30 minutes

In this lab you will improve the CMS from the previous lab, by making the firing sequence configurable using a list bean. The controller code will reduce to a very simple loop over the configured bean, which in turn will link in the transformers and pipes.

In optional steps you can also flesh out the full set of CMS pathways, adding a number of XML-to-HTML transformations in parallel with the text formatting you’ve already done.

Detailed instructions are found at the end of the chapter.

LAB 3B

Page 116: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

106

Autowiring

• In a more ambitious move, Spring IoC containers are also designed to detect bean dependencies where they are not explicitly stated.

• This is called autowiring, and you can declare any bean to take advantage of it, by setting autowire to one of four heuristics:

− byName, asking the container to seek out a bean whose name matches the name of a property

− byType, which will match a bean whose type satisfies the dependency by being either the same or assignable to the property type – this is the most common type of autowiring

− constructor, which is type-based matching for constructor arguments

− autodetect, which chooses either byType or constructor based on the availability of a default constructor on the bean

• Autowiring has a fancy feel to it, but it can’t solve every dependency problem, and it also makes the configuration harder to read and to navigate.

• Even Spring’s own documentation urges caution with this feature.

• But it is used heavily in the Web module – where there are several singletons that are easily distinguished by type.

Page 117: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

107

Autowiring

• In Examples/Autowiring, a very simple example illustrates the labor savings derived by autowiring a chain of three beans.

• See Objects.xml, where two such chains are declared, for analogous systems of classes A/B/C and X/Y/Z.

− The first chain is constructed explicitly, using inner beans: <bean id="A" class="cc.A" > <constructor-arg> <bean id="B" class="cc.B" > <constructor-arg> <bean id="C" class="cc.C" > <constructor-arg value="You found me!" /> </bean> </constructor-arg> </bean> </constructor-arg> </bean>

− The second is autowired: <bean id="X" class="cc.X" autowire="constructor" /> <bean id="Y" class="cc.Y" autowire="constructor" /> <bean id="Z" class="cc.Z" > <constructor-arg value="You found me again!" /> </bean>

• Build and test: build run You found me! You found me again!

EXAMPLE

Page 118: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

108

Aliases

• A bean can have more than one name.

• Declare as many aliases for a bean as you like, as shown below. <alias name="theBean" alias="alternateName" />

• This allows some flexibility in mapping names to beans, as many names can resolve to the same bean definition.

− Perhaps many references in an application will each eventually resolve to distinct beans which are refined over time.

− For the 1.0 release, they all resolve to a default bean.

− Then the configuration can evolve without requiring any recompilation or redeployment of code.

• Note that a singleton is still a singleton: giving a bean an alias does not result in an additional instance at runtime.

Page 119: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

109

Wholesale Beans

Suggested time: 30-45 minutes

In this lab you will complete the implementation of an application that processes product orders for a wholesale distribution company. Client retailers maintain files containing regular orders for their products of interest, and one of the jobs is to configure the list of these “feeds.” A fulfillment engine processes these, also applying a locale-specific tax policy, and produces a sales record. This is then post-processed to produce an HTML report.

Detailed instructions are found at the end of the chapter.

LAB 3C

Page 120: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

110

Order of Instantiation

• Often the order in which various beans are created is unimportant to the application logic.

• But sometimes it matters very much that bean A is created and initialized before bean B gets a chance to use it.

• Different IoC containers will pursue different policies in this regard.

• The XmlBeanFactory will instantiate only on a call to getBean.

− Supporting beans are then instantiated on demand – that is, as necessary to satisfy dependencies of beans as they are created.

• Later we’ll see that the web application context is more eager to create beans, publishing all its singletons when the web application is installed.

Page 121: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

111

Controlling Instantiation Timing

• Various attributes can be defined in the configuration to customize the timing by which the container will create your beans.

• The primary means of control over the timing of object creation is the lazy-init attribute, which will convert a singleton bean from eagerly instantiated to instantiated-on-demand.

− You can also define default-lazy-init for an entire context.

• Another issue arises when there is a bean dependency that isn’t apparent from the information in the configuration file.

− Perhaps bean A requires bean B to exist prior to a call it makes on a third bean, or that a property on B be set before A makes a call to one of B’s methods.

− None of this would show up in a bean definition for A or B.

• In such cases you can explicitly state the dependency with the depends-on attribute.

− As in A depends-on=“B”.

• In the JavaBean itself, you can request a notification when your instance has been created and all properties have been set.

public interface InitializingBean { public void afterPropertiesSet (); }

− This can be used to trigger additional bean loading, potentially resulting in a domino chain of beans loading one another.

Page 122: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

112

Lazy Instantiation

• In Demos/Lazy, we’ll experiment with instantiation policies and declarations in the Wholesale application.

− The completed demo is in Examples/Wholesale/Beans/Step5.

1. Build and run the application, which is just as we left it at the end of Lab 3C.

build run Total sales: 10,075.65 2. Now, for each of four classes – cc.sales.Fulfillment,

cc.sales.ListOfBatches, cc.sales.MASalesTax, and cc.tools.xml.XSLTransformer – add code to print a line to the console when the class is instantiated. (For MASalesTax you’ll need to create an explicit no-argument constructor for this purpose.)

3. Build and test again, and see the order in which the objects are created.

build run MASalesTax instantiated. Fulfillment instantiated. ListOfBatches instantiated. Total sales: 10,075.65 XSLTransformer instantiated. 4. Not much to surprise us here ... the tax object has to be created before

the fulfillment object can be configured, but otherwise this is create-on-demand.

DEMO

Page 123: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

113

Lazy Instantiation

5. Open src/Controller.java, and replace XmlBeanFactory with FileSystemXmlApplicationContext. You’ll have to import this class from org.springframework.context.support.

BeanFactory factory = new FileSystemXmlApplicationContext ("SalesObjects.xml"); 6. Try it again: build run XSLTransformer instantiated. MASalesTax instantiated. Fulfillment instantiated. ListOfBatches instantiated. Total sales: 10,075.65 7. Hmm! An application context will eagerly instantiate and configure

all singleton beans. There is no guarantee of the order of instantiation, but it seems that this factory works from the top of the configuration file to the bottom.

8. What if the transformer object pre-loaded some or all of its information? Say we configure it with a source file TotalSales.xml and it tries to read in the file contents as soon as we give it the filename. In this order of instantiation, there’s no file to read!

DEMO

Page 124: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

114

Lazy Instantiation

9. We can convert the transformer back to a create-on-demand policy by declaring lazy-init for it:

<bean id="PostProcessor" class="cc.tools.xml.XSLTransformer" lazy-init="true" > 10. Test now: run MASalesTax instantiated. Fulfillment instantiated. ListOfBatches instantiated. Total sales: 10,075.65 Transformer instantiated.

DEMO

Page 125: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

115

SUMMARY

• The ability to assemble graphs of objects, of arbitrary complexity, completes the IoC container, and it’s with these features that the value of IoC really comes home:

− Dependency injection

− Populating collections

− Generally, being able to hide all the details of object configuration behind a few strings, perhaps even one string, the bean name for the top object of a tree

• As we want to control object creation, we may also want control over the timing of object creation, and Spring provides a few means to influence the behavior of the IoC factory.

− However, when a sequence of creation events must be strictly followed, it’s a good idea to implement that sequence yourself, perhaps in an Abstract Factory; then, publish that factory to the IoC container.

Page 126: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

116

Transformation Chains

In this lab you will use a combination of simple property values and injected bean dependencies to configure a complex tree of XML transformations that produces an array of output documents.

Lab workspace: Labs/Lab3A

Backup of starter code: Examples/Transformer/Step6

Answer folder(s): Examples/Transformer/Step7

Files: src/cc/tools/xml/XSLTransformer.java src/cc/tools/xml/Pipe.java src/Controller.java CMS.xml (to be created)

Instructions:

1. Build and test the existing system, which carries out the same simple transformation as in previous steps of this case study:

build run This is the result I wanted! 2. You may want to review the XSLTransformer and Pipe classes – the complete paths

are shown above. Also, notice that there is a new source document Input/Listings.xml. This functions as a mini-database of listings of available rental housing: there are 16 units listed, with various attributes including number of bedrooms, rent, date available, and accessibility to tenants who use wheelchairs.

3. A set of transformations for the CMS has been prepared in the Transforms directory. If you’re familiar with XSLT you might want to review these as well, but we’ll briefly explain the function of each as we come to it.

4. Create a subdirectory called Output, which will hold your transform results. (In the answer directory you’ll find the results of all the transforms diagrammed in the lab overview; by the end of the lab you’ll be producing an identical set of documents.)

5. Open Controller.java and change the name of the configuration file from “TransformerObjects.xml” to “CMS.xml” – you’ll create this file shortly.

6. Change the name of the retrieved bean from “Transformer” to “summaryText”.

LAB 3A

Page 127: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

117

Transformation Chains LAB 3A

7. Create the new CMS.xml by copying TransformerObjects.xml. Set up a “summaryText” transformation by changing the values for the declared bean as shown below:

<bean id="summaryText" class="cc.tools.xml.XSLTransformer" > <constructor-arg value="Transforms/SummaryText.xsl" /> <property name="sourcePath" value="Input/Listings.xml" /> <property name="resultPath" value="Output/Summary.txt" /> </bean> 8. Build and run, and you’ll see your new transformation has produced output as

directed. Type the contents of the Summary.txt file, or view it in an editor: build run (no output) type Output\Summary.txt 33 Boynton Street #2, renting at $1400. Available 2002-08-01. 501 Centre Street #1F, renting at $800. Available 2002-08-01. 54 Hews Street #3, renting at $600. Available 2002-09-01. ... 6 Oak Terrace #2, renting at $1250. Available 2002-09-01. 9. Declare a second bean “detailText” with different transform path

(“Transforms/DetailText.xsl”) and result path (“Output/Detail.txt”), but the same source path.

10. Add code to Controller.java to trigger this transform as well.

11. Build and test, and see the new file Detail.txt in the Output directory: build run type Output\Detail.txt ... ---------------------------------- 6 Oak Terrace #2 Jamaica Plain, MA Bedrooms: 2 Floor: 1 Rent: $1250/month Date available: 2002-09-01 Contact: Judy Trueblood 555-464-9797 [email protected]

Page 128: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

118

Transformation Chains LAB 3A

12. So, you’ve completed two paths from the complete system diagrammed in the lab overview:

Now, we’ll start using Pipe beans as intermediate stages in chain of transformations, starting with this two-step process to filter and then summarize the content:

13. Declare a third bean called “accessibleUnits” whose type is the Pipe class. It has no

properties.

14. Now declare a new XSLTransformer bean called “accessible”. Use the same sourcePath again. For the constructor argument use a third XSLT file “Transforms/Accessible.xsl” – this XML-to-XML transformation produces a document of the same content model as the source, but filters out units that are not wheelchair-accessible.

For the result, change the property name from resultPath to resultPipe, and instead of a value, use a ref to the “accessibleUnits” bean. This connects the output of the transformer to the Pipe so that it can be used as the source for a second transformation.

15. Declare a fourth XSLTransformer called “accessibleSummaryText”. This one will have a sourcePipe of “accessibleUnits”, will use the “Transforms/SummaryText.xsl” (exactly the same one used in the “summaryText” transform that you started with), and a resultPath of “Output/AccessibleSummary.txt”.

16. Add code to Controller.java to trigger both of these new transformations, in order.

accessible SummaryText

Accessible Summary.txt

accessibleUnits

SummaryText.xsl Accessible.xsl

Listings.xml accessible

SummaryText.xsl

Summary.txt

Detail.txt

summaryText

detailText

DetailText.xslListings.xml

Page 129: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

119

Transformation Chains LAB 3A

17. Build and test and you’ll see that your two-transformation chain has produced a summary of the five wheelchair-accessible units:

build run type Output/AccessibleSummary.txt 501 Centre Street #1F, renting at $800. Available 2002-08-01. 26 Hanover Lane, renting at $650. Available 2002-09-01. 1 Monroe Place, #7G, renting at $1200. Available 2002-06-01. 75 Clarendon Street #1A, renting at $980. Available 2002-10-01. 22 Shirley Road, renting at $600. Available 2002-07-01. 18. From here, you can do as much or as little of what’s left as you like. Producing the

AccessibleDetail.txt file is trivial at this point; producing the Statistics.txt file is very similar to what you just did, which is a two-step process of XML-to-XML (this time not filtering but extracting aggregate statistics about average rent for different sizes of apartments) and then XML-to-text. Try these now if you like – the detail content is similar to what you’ve seen, and Statistics.txt should look like this:

The average rent for a studio is $816.6666666666666. The average rent for a 1-bedroom is $891.875. The average rent for a 2-bedroom is $1387.5. The average rent for a 3-bedroom is $1550.

In these remaining explicit instructions we’ll focus on the one distinct process we haven’t yet configured, which is a pipe-to-pipe transformation. To produce AccessibleStatistics.txt requires a three-step process: filter to “accessibleUnits”; derive “accessibleStatistics” from that Pipe to a second Pipe; and then format the results to a text file:

accessible Units

Accessible.xsl

Statistics.xsl

accessible Statistics

accessible StatisticsText

Accessible Statistics.txt

StatisticsText.xsl

Listings.xml accessible

accessibleStats

Page 130: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

120

Transformation Chains LAB 3A

19. You already have the first pipe; declare a second one now called “accessibleStatistics”.

20. Define an XSLTransformer called “accessibleStats” that uses “accessibleUnits” as its sourcePipe and “accessibleStatistics” as its resultPipe and uses the “Transforms/Statistics.xsl” as the transform path.

21. Now declare a final transformer bean “accessibleStatisticsText” to carry results from that second pipe to “Output/AccessibleStatistics.txt” as the resultPath, using “Transforms/StatisticsText.xsl”.

22. Update Controller.java to run these two new transformations after all the others.

23. Build and test and see your filtered statistics: build run type Output/AccessibleStatistics.txt The average rent for a 1-bedroom is $757.5. The average rent for a 2-bedroom is $1200.

Page 131: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

121

The Firing Sequence

In this lab you will improve the CMS from the previous lab, by making the firing sequence configurable using a list bean. The controller code will reduce to a very simple loop over the configured bean, which in turn will link in the transformers and pipes.

In optional steps you can also flesh out the full set of CMS pathways, adding a number of XML-to-HTML transformations in parallel with the text formatting you’ve already done.

Lab workspace: Labs/Lab3B

Backup of starter code: Examples/Transforms/Step7

Answer folder(s): Examples/Transforms/Step8 (intermediate) Examples/Transforms/Step9 (final)

Files: CMS.xml src/Controller.java

Instructions:

1. If you didn’t complete the previous lab, you might want to build and test the starter code, and observe the results in the Output directory.

2. In CMS.xml, add support for the utility schema by defining the util: namespace prefix and identifying the standard schema location – see the earlier page in the chapter entitled “The Spring Utility Schema” for the exact URI and location.

3. Define a new bean using the <util:list> element, and call it “firingSequence”.

4. Add one <ref> child element to this list for each transformation in the sequence, with a bean attribute giving the name of the corresponding transformer bean. In other words, reproduce the sequence that’s currently carried out in a series of expressions in Controller.java – but now it’s just a simple list of beans.

5. Remove the code in the try block of Controller.java’s main method.

6. In that now-empty try block, derive a reference to a bean called “firingSequence” and downcast it to a List<XSLTransformer>.

7. For each element in the list, call transform.

8. Build and test, and you should see the application working as before, producing the same six output files. But now, you can put Controller.java away; everything you need to say about CMS pathways – transformers, pipes, input and output paths, and the firing sequence – is configured for the application via the IoC container.

(This is the intermediate answer in the Step8 directory.)

LAB 3B

Page 132: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

122

The Firing Sequence LAB 3B

Optional Steps

9. To exercise this new freedom, try adding another transformation to the system. For each of the XML-to-text transformations currently in use, there is a corresponding XML-to-HTML transformation that will produce a simple web page. For example, if you add the following bean:

<bean id="summaryHTML" class="cc.tools.xml.XSLTransformer" > <constructor-arg value="Transforms/SummaryHTML.xsl" /> <property name="sourcePath" value="Input/Listings.xml" /> <property name="resultPath" value="Output/Summary.html" /> </bean>

... and add a reference to this bean to the firing sequence, you’ll see a new file Summary.html in the Output directory when you run the application again. (And of course there’s no longer any need to rebuild.)

10. Add a similar bean to carry out a detail-HTML transformation, and you’ll be able to

click the links in the summary page to see sections of the detail page. You can add all six HTML transformations, side-by-side with the existing text transformations, and see the various pages in the Output directory.

(This is the final answer in the Step9 directory.)

Page 133: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

123

Wholesale Beans

In this lab you will complete the implementation of an application that processes product orders for a wholesale distribution company. Client retailers maintain files containing regular orders for their products of interest, and one of the jobs is to configure the list of these “feeds.” A fulfillment engine processes these, also applying a locale-specific tax policy, and produces a sales record. This is then post-processed to produce an HTML report.

Lab workspace: Labs/Lab3C

Backup of starter code: Examples/Wholesale/Beans/Step1

Answer folder(s): Examples/Wholesale/Beans/Step2 (intermediate) Examples/Wholesale/Beans/Step3 (intermediate) Examples/Wholesale/Beans/Step4 (final)

Files: SalesObjects.xml (to be created) src/Controller.java src/cc/sales/ListOfBatches.java (to be created)

Instructions:

1. Review the domain model as implemented so far. The ListOfBatches class doesn’t exist yet; it will bring the whole persistent model of Order objects into play, with the help of the OrderDAO. The Fulfillment engine combines a batch of orders with a configurable tax policy to derive final sales information, which it saves to a file.

LAB 3C

Page 134: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

124

Wholesale Beans LAB 3C

2. Open the Controller source file and implement main to carry out the task of loading configured feeds and processing them. First, derive a BeanFactory based on the file SalesObjects.xml – you’ll create this in a moment to satisfy the requirements of this Java class.

3. Get a Fulfillment object called “FulfillmentEngine”.

4. Get a List<List<Order>> called “OrdersToProcess”, and pass this to the fulfillment engine’s fulfill method.

5. build to check your code with the compiler.

6. Now create your SalesObjects.xml configuration file. Get the usual shell content from a previous example, and declare your “FulfillmentEngine” bean. This class’ constructor takes two arguments: a Taxation object and a filename to which it will write the XML record of orders filled. Use an inner bean of class cc.sales.MASalesTax for the first argument, and for the second pass “TotalSales.xml”.

You may want to validate your configuration file at this point.

7. Now, how to derive a list of lists of Order objects? You know how to build a list, and even a list of lists. But how to get those orders? They are loaded from prepared files by the OrderDAO, and so perhaps that would be the approach: let OrderDAO.load be the factory method. Ah – but here’s a weak spot in Spring’s factory support. You can declare a static factory method on the target class itself, or a separate factory bean with an instance method – but not a static method on a separate factory bean.

You could refactor OrderDAO somehow, but probably the best approach is to wrap it in a new JavaBean. This is where ListOfBatches comes in.

8. Create this new class, in src/cc/sales/ListOfBatches.java. It’s job is to be a JavaBean that takes a list of strings, processes a file of the given name for each one, and thus creates a list of lists of orders (since each file holds a list of orders and you’ll handle multiple files). This list of lists will be available as a property on the bean.

So, given a list of strings called filenames, and a private field batches of type List<List<Order>>, the interesting bit is

for (String filename : filenames) batches.add (OrderDAO.load (filename));

... and your constructor should be signed to throw the java.io.IOException.

Page 135: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

125

Wholesale Beans LAB 3C

9. When your new class is complete and compiled, return to SalesObjects.xml and declare a bean of that type called “OrdersToProcess”. Now, your job here has gotten easier: just give this bean a constructor argument which is a list of the following filenames:

Feeds/Apples.txt Feeds/Furniture.txt Feeds/MixedBag.txt Feeds/PartyFavors.txt

Now, if you test at this point, things won’t go so well – remember why? We left a little disconnect back down the road ...

10. Remember that Controller.java still expects this bean to be a List, not a bean that wraps a list. So it will fail when it tries to downcast the bean returned by the factory. Instead, change the code there to correctly derive a ListOfBatches, and then when calling fulfill, pass the results of a call to getBatches on that bean, rather than the bean itself. As in:

engine.fulfill (lob.getBatches ()); 11. Now build and test. You should see complete results now, which include a line to the

console and a new file TotalSales.xml. (This is the intermediate answer in Step2.) build run Total sales: 10,075.65 type TotalSales.xml ... <Sale> <Product>Sideboard</Product> <Price>1800.0</Price> <Quantity>1</Quantity> <Total>1903.5</Total> </Sale> </Sales> Optional Steps

12. Let’s give autowiring a try. Make the tax policy a top-level bean – but don’t bother giving it a name, just keep the class as defined and leave it at that.

13. Now, remove the first constructor argument from the “FulfillmentEngine” bean.

14. Define autowire=“constructor” on that bean. The idea is that there’s only one bean defined that could satisfy the dependency, given its type, so it should be found by the container when we ask it to auto-wire.

Page 136: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

126

Wholesale Beans LAB 3C

15. Give this a try – this is the intermediate answer in Step3. run Total sales: 10,075.65 16. Finally, let’s try wiring up one of our XSLT transformers to the output of this

application. There is a prepared transform in SalesReport.xsl, and you can copy the XSLTransformer class and the TransformerObjects.xml configuration from Examples/Transformer/Step5.

17. Edit TransformerObjects.xml to reflect new inputs and outputs. The source file is now TotalSales.xml; the transform is SalesReport.xsl, and you can state any filename you want for the HTML output.

18. Now, you could have Controller load a second bean factory from this new file, but instead, try a new trick: import the file into your existing configuration. As the first child element of <beans>, add:

<import resource="TransformerObjects.xml" /> 19. Add code to Controller.java to get the transformer bean and to call its transform

method. Import the package cc.tools.xml into this source file.

20. You will have to modify build.bat to include the new package in the compile as well: javac -d build -classpath %SPRING_HOME%\dist\spring.jar src\cc\sales\*.java cc\tools\xml\*.java src\*.java

Page 137: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 3

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

127

Wholesale Beans LAB 3C

21. Build and test. After the application runs, you should see a new HTML file in the lab directory, and in a browser it will look like this:

This is the final answer in Step4; the output file is Report.html.

Page 138: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,
Page 139: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

CHAPTER 4

VALIDATION

Page 140: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

130

OBJECTIVES

After completing “Validation,” you will be able to:

• Implement validators to assert constraints on bean state.

• Invoke validators on target objects and graphs of objects, and organize their error reporting using centralized error compilations.

• Define message keys to take advantage of resource localization.

• Delegate from one validator to another to match the logical decoupling in the target model.

− Use nested paths in error-reporting objects to correctly support such “nested validators.”

Page 141: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

131

We All Seek Validation

• Most applications – very nearly all web applications – have to consider the problem of validating user input.

• Spring therefore makes validation fundamental:

− It is part of the core module – Spring’s authors understand that data validation, is at least potentially, business logic. (At the very least, we can say it’s not a web-specific function, and so must be decoupled from any web artifacts.)

− It is integrated tightly with more general exception and error-handling mechanisms.

− It is entirely flexible, as any class can be a validator for any other class – or for itself, though that’s not generally the idea.

Page 142: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

132

Spring Validation

• Spring’s model for validation is expressed in the package org.springframework.validation:

− Any class can act as a validator; it must only implement the

Validator interface, which has just two methods.

− Validation is an error-reporting process, and there is a common structure for gathering errors over some error-handled duration: this is the Errors interface.

− A class utility ValidationUtils serves two purposes: it can be used to launch validation on a particular object, and validators can use it to simplify reporting of the most common validation errors, which are those having to do with missing or empty fields.

Page 143: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

133

The Validator and Errors Interfaces

• A validator is just a class that implements a validate function and can announce what class or classes it supports as targets:

public interface Validator { public boolean supports (Class); public void validate (Object, Errors); }

• Given a target object, a validator is responsible for reporting any and all errors through the given errors object.

− Following is a partial listing: public interface Errors { public String getObjectName (); public void reject (String code); public void rejectValue (String field, String code); public boolean hasErrors (); public List getAllErrors (); public List getGlobalErrors (); public List getFieldErrors (); public List getFieldErrors (String field); }

• So the model allows for lists of errors “globally” – meaning for the whole target object – and for each field on the object.

Page 144: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

134

The ValidationUtils Class

• ValidationUtils is a gathering point for utility methods serving different functions for different types of callers.

public abstract class ValidationUtils { public static void invokeValidator (Validator, Object, Errors); public static void rejectIfEmpty (Errors, String field, String code); public static void rejectIfEmptyOrWhitespace (Errors, String field, String code); }

• Any party wanting to trigger validation can do so with a call to invokeValidator.

− The method won’t conjure up the validator or errors object for you, but it will check that the validator supports the target object before calling validate, and do appropriate logging and error reporting.

• Validators themselves can use the rejectIfEmpty and rejectIfEmptyOrWhitespace to record these common error cases easily.

− Many validators are essentially scripts of calls to these methods.

− Not all overloads of these two methods are shown; there are others, analogous to the Errors methods that were omitted on the previous page, that provide default message values and/or arguments for replaceable parameters in the message.

Page 145: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

135

Context for the Errors Object

• You may have noticed the absence of a parameter identifying the object of validation in several of the methods we’ve just seen:

− Errors.rejectValue accepts a field name, but no object reference.

− ValidationUtils.rejectIfEmpty and related methods are similar: they take field names, but nowhere is a reference to the object being validated passed to this method.

• If these methods aren’t given any reference to the object that they must test, how can they carry out their work?

• This wouldn’t be obvious, since we’ve yet to see how an Errors object is instantiated, but the object reference is given to the Errors object initially.

• So the validator, the Errors object, and ValidationUtils all can see the target object in some way:

− An Errors object holds this context information and uses it in error reporting.

− ValidationUtils takes advantage of this connectivity, since it receives a reference to the Errors object as an argument to its methods.

Page 146: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

136

An Ellipsoid Validator

• In Examples/Ellipsoid/Beans/Step3 we see EllipsoidValidator, which assures that all values on an Ellipsoid are valid:

public class EllipsoidValidator implements Validator { public boolean supports (Class cls) { return cls.equals (Ellipsoid.class); } public void validate (Object object, Errors errors) { Ellipsoid target = (Ellipsoid) object; if (target.getA () <= 0) errors.rejectValue ("a", "validation.Ellipsoid.a", "Semi-axis A must be a postive number."); if (target.getB () <= 0) errors.rejectValue ("b", "validation.Ellipsoid.b", "Semi-axis B must be a postive number."); if (target.getC () <= 0) errors.rejectValue ("c", "validation.Ellipsoid.c", "Semi-axis C must be a postive number."); } }

• We’ll give this validator a spin in a moment.

EXAMPLE

Page 147: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

137

The MessageSource Interface

• Though Spring includes robust support for internationalization, most developers don’t encounter it until they try to report errors.

• Validation and other error mechanisms plug into the i18n support in Spring, and this makes it advisable to get at least a basic string table in place for your application.

• Most error-reporting functions are overloaded.

− We’ve seen the ones that only take an error code.

− For each of these there are often two others: one that adds a default value in case the error code is not resolved, and another that adds a default value and an array of arguments for replaceable parameters that may be in the error string.

• To convert message codes (and arguments) into messages, call a method on some implementation of MessageSource, from package org.springframework.context:

public interface MessageSource { public String getMessage (String code, Object[] args, Locale locale); public String getMessage (String code, Object[] args, String default, Locale locale); public String getMessage (MessageSourceResolvable resolvable, Locale locale); }

Page 148: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

138

Deriving a MessageSource

• A MessageSource implementation will represent one or more message bundles.

− These are declared in the usual way, according to Java i18n standards, and resolved by locale at runtime.

• Any ApplicationContext is automatically a MessageSource.

− Standard implementations automatically look for a bean of a specific name, “messageSource”, and make that their delegate.

• Ordinary BeanFactory implementations don’t have it so easy.

− An application must instantiate its own message source – preferably by way of Spring IoC – and populate it with message keys and strings.

− The likely candidate here is ResourceBundleMessageSource, from org.springframework.context.support.

− This can be primed with the base name for a message bundle, which it will load and represent through the MessageSource methods.

• For our upcoming lab, we’ll do without i18n support.

− Notice that the error reporting in EllipsoidValidator supplies default values throughout; you’ll do the same thing with the OrderValidator you’re about to build.

• Our web applications will take advantage of the much greater facility for connecting message bundles found in XmlWebApplicationContext.

Page 149: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

139

Putting Validators to Work

• Standalone Spring applications can instantiate the appropriate objects by hand, and call ValidationUtils.invokeValidator.

− Create the validator of choice.

− BeanPropertyBindingResult is a handy Errors implementation – find this right here in package org.springframework.validation.

• Then report errors in any appropriate manner.

− From the Errors object, you can see lists of all errors, all global errors, all field-oriented errors, or errors for a particular field.

− Each list will hold objects of type ObjectErrors – methods specific to fields will return objects downcastable to FieldErrors.

− These have toString methods that dump all known values to a log, and also methods to provide the individual values that went into the error report, to be formatted into more user-friendly output.

• Web applications (those lucky sods) enjoy more infrastructure here as well.

− Typically, errors will be reported based on the binding of request parameters to a command object, as well as on subsequent validation of the object.

− Default and configurable error handlers will log the errors.

− Custom tags in JSPs will report the errors to the web user.

• We’ll revisit this in a later chapter, after we get some Spring Web MVC under our belts.

Page 150: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

140

Validating Ellipsoids

• In Examples/Ellipsoid/Beans/Step3, the Controller class has been enhanced to perform validation prior to reporting on the requested bean:

public static void reportOn (Ellipsoid subject) { final Validator validator = new EllipsoidValidator (); Errors errors = new BeanPropertyBindingResult (subject, "ellipsoid"); ValidationUtils.invokeValidator (validator, subject, errors); if (errors.hasErrors ()) { System.out.println ("Ellipsoid is invalid:"); for (Object error : errors.getAllErrors ()) System.out.println (error); return; } System.out.println ("Three-dimensional ellipsoid -- properties:"); ...

• Ellipsoids.xml now has three new beans, none of which are valid.

EXAMPLE

Page 151: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

141

Validating Ellipsoids

• Build and test – against one of the good beans first: build run cool Three-dimensional ellipsoid -- properties: Semi-axis A: 4.0 Semi-axis B: 4.0 Semi-axis C: 4.0 Volume: 268.082573106329 Type: Sphere Definition: Where A = B = C, offering perfect rotational symmetry in all three dimensions.

• Now try the “unacceptable” bean, whose values are (0, 1, 1): run unacceptable Ellipsoid is invalid: Field error in object 'ellipsoid' on field 'a': rejected value [0.0]; codes [validation.Ellipsoid.a.ellipsoid.a, validation.Ellipsoid.a.a, validation.Ellipsoid.a.double, validation.Ellipsoid.a]; arguments []; default message [Semi-axis A must be a postive number.]

• Try the other two as well, which are:

− notCool (-4, -4, -4)

− clearlyInferior (2, 3, -4)

EXAMPLE

Page 152: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

142

Single-Order Validation

Suggested time: 15 minutes

In this lab you will implement a validator for the Order bean and apply it to sales data prior to fulfilling orders.

Detailed instructions are found at the end of the chapter.

LAB 4A

Page 153: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

143

Nesting Validators

• It’s natural to define a validator for each domain class.

• Where one domain class relies on another as a collaborator, its validator will typically delegate to the validator for that collaborator – and so on from the head of an object graph to all the nodes in the graph.

• There is one complication, concerning the Errors object:

− On one hand, we want a single compilation of all errors encountered anywhere in the process; we wouldn’t want a distinct Errors object for each node in the object graph.

− On the other hand, we know that both the validators and Errors are contextual: each “knows” what object it was meant to work with – and they must have the same idea which object that is!

− This threatens to frustrate good decoupling of validation logic, because lower-level validators will ask the Errors object to, for instance, reject a named field – and the Errors object won’t be able to find that field!

AddressValidator

CompanyValidator

DepartmentValidator

EmployeeValidator

Address

Company

Department

Employee

Address

Errors

Page 154: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

144

Nested Property Paths

• We’ve discussed Spring’s support for compound property names, of forms such as a.b.c and a[0].b.

• As we get deeper into working with command objects, and especially with validation, we see more of Spring’s support for what are correctly called nested properties.

• Nested properties are essential to managing complex data models; the tension between the “global” context of the Errors object and the “local” context necessary for a given validator is just one example of this need.

• The solution here is to allow validators to push and pop fragments of compound property paths into the Errors object.

public void pushNestedPath (String partialPath); public void popNestedPath ();

− This allows the object to maintain two contexts: the top-level object it was given originally, and a reference to the object currently under scrutiny.

− For our validators so far, these have always been the same object.

− When drilling down through a more complex object graph, often they will not be the same object.

− The rest of the field-sensitive methods on Errors, including rejectValue, will treat field names passed as arguments as being relative to the current nested path.

Page 155: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

145

Wholesale Validation

Suggested time: 30 minutes

In this lab you will complete the validation layer for the Wholesale application. You already have an OrderValidator ready to roll. You will build a higher-level validator for ListOfBatches, that delegates to the OrderValidator for each of its sub-parts. You’ll put this new validator in play from the Controller class, simplifying the logic there.

Detailed instructions are found at the end of the chapter.

LAB 4B

Page 156: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

146

SUMMARY

• Data validation is a general concern for most applications, and Spring makes it straightforward to support validation logic in any tier, including in the business tier with no ties to web or other presentation decisions.

• Internationalization, including for error messages, is practicable for standalone applications, but much easier for web applications, thanks to some helpful code in the Web module.

• The errors and utilities objects use nested paths to resolve the tension between their global and local responsibilities, when nested validators are used to check a complex graph of objects.

Page 157: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

147

Single-Order Validation

In this lab you will implement a validator for the Order bean and apply it to sales data prior to fulfilling orders.

Lab workspace: Labs/Lab4A

Backup of starter code: Examples/Wholesale/Beans/Step6

Answer folder(s): Examples/Wholesale/Beans/Step7

Files: src/Controller.java src/cc/sales/OrderValidator.java (to be created)

Instructions:

1. Create a new class cc.sales.OrderValidator that implements the Validator interface.

2. Implement supports in the usual way; see the EllipsoidValidator example.

3. Define your implementation of validate, with parameters object and errors as shown in the example.

4. Start your implementation of validate by downcasting the first argument to type Order, and assigning that to a local variable target.

5. The product name is required, so call ValidationUtils.rejectIfEmptyOrWhitespace, passing four arguments: errors, the field name “product”, a message key of your own choosing (we won’t get to use it in this lab anyway!), and a default error message.

6. If a call to target.getPrice returns a number less than or equal to zero, call errors.rejectValue, passing the field name “price”, another dummy message key, and the “real” (default) error message.

7. Do the same thing with target.getQuantity, which must be positive.

8. Build at this point to check your coding so far.

9. Open Controller.java and add code before the call to engine.fulfill. First, initialize an OrderValidator called orderValidator.

10. Create an outer loop over the List<Order> objects in the list returned by lob.getBatches.

11. Create an inner loop over the Order objects themselves.

LAB 4A

Page 158: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

148

Single-Order Validation LAB 4A

12. In this inner loop, add code similar to what you saw in the EllipsoidValidator example: initialize an Errors object; call invokeValidator, and check if errors.hasErrors. If so, loop through them and produce them to the console before aborting the process.

Thus only if there are no validity errors will engine.fulfill be called.

13. Build and test, and, lo and behold, there is a validity error! build run Validation failed: Field error in object 'order' on field 'quantity': rejected value [0]; codes [validation.Order.quantity.order.quantity,validation.Order.quantity.quantity,validation.Order.quantity.int,validation.Order.quantity]; arguments []; default message [Quantity must be a positive integer.] 14. But, which Order object was invalid? Since your Errors object is created with the

individual Order instance as its scope, the error messages don’t carry that contextual information. You could find this out with some good, old-fashioned debugging or diagnostics, but in the upcoming lab you’re going to improve and broaden your validation logic anyway, and be able to identify the culprit with minimal fuss.

So, let’s leave it be for now ...

Page 159: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

149

Wholesale Validation

In this lab you will complete the validation layer for the Wholesale application. You already have an OrderValidator ready to roll. You will build a higher-level validator for ListOfBatches, that delegates to the OrderValidator for each of its sub-parts. You’ll put this new validator in play from the Controller class, simplifying the logic there.

Lab workspace: Labs/Lab4B

Backup of starter code: Examples/Wholesale/Beans/Step7

Answer folder(s): Examples/Wholesale/Beans/Step8

Files: src/cc/sales/ListOfBatchesValidator.java (to be created) src/Controller.java

Instructions:

1. Create a new class cc.sales.ListOfBatchesValidator that implements the Validator interface. You can use OrderValidator as a template; the supports method is entirely boilerplate.

2. To implement validate, first downcast the Object parameter to a ListOfBatches – call this target.

3. Call ValidationUtils.rejectIfEmpty, passing your errors object, the field name “batches”, the error code “validation.ListOfBatches.batches”, and a default message saying there must be at least one batch of orders.

4. Instantiate an OrderValidator – call it orderValidator – which you’ll use repeatedly in the loop you’re about to write.

5. Now iterate through the batches on the target object, and all the orders on each batch. For each order, make a call to orderValidator.validate, passing along the errors object to gather all object and field errors.

6. In the main method of Controller.java, you can now simplify the code for validating the list of batches, by invoking the ListOfBatchesValidator once on the whole lob target. The validator now does all the looping and delegating to OrderValidator, so you don’t have to duplicate that logic here. Just create your Errors object, invoke the validator, and report any errors.

LAB 4B

Page 160: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

150

Wholesale Validation LAB 4B

7. Build and test your code. build run Exception in thread "main" org.springframework.beans.NotReadablePropertyException: Invalid property 'product' of bean class [cc.sales.ListOfBatches]: Bean property 'product' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? etc. 8. This message, and then also the exception stack trace that isn’t shown above, make it

clear that the error originates from the OrderValidator. Though you haven’t yet seen this class work, assume for the moment that it is correctly implemented. What might be going on that would make this class function incorrectly?

9. Well, the preconditions for the call to OrderValidator.validate are basically the target object – which is what it is, good or bad – and the errors object. And a closer look at the error message shows that we’re trying to check a property “product” on an object of type ListOfBatches. Something’s out of synch.

Here we’re seeing the need for nested properties. The Errors object keeps a reference to the target object, which is the ListOfBatches. But the OrderValidator doesn’t even know about that class; it just wants to validate a single Order, and it assumes that the Errors object given to it knows what it’s doing. Right now it doesn’t – but it could, if we’d just tell it!

10. Before calling OrderValidator.validate, call pushNestedPath on the errors object, passing a string of the form “batches[bat][ord] where bat and ord are the index values for the position in the nested loop over batches and orders. This way, when the OrderValidator calls rejectIfEmptyOrWhitespace, the errors object will know to translate “product” to “batches[bat][ord].product” – which is the appropriate property name, since the embedded target object is a ListOfBatches.

After the call to OrderValidator.validate, call popNestedPath on the errors object.

Page 161: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 4

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

151

Wholesale Validation LAB 4B

11. If you test now, you should get a clear error message that tells you exactly where that bad datum is that we’ve been living with since the previous lab:

build run Validation failed: Field error in object 'listOfBatches' on field 'batches[2][2].quantity': rejected value [0]; codes [validation.Order.quantity.listOfBatches.batches[2][2].quantity,validation.Order.quantity.listOfBatches.batches[2].quantity,validation.Order. quantity.listOfBatches.batches.quantity,validation.Order.quantity.batches[2][2].quantity,validation.Order.quantity.batches[2].quantity,validation.Order.quantity.batches.quantity,validation.Order.quantity.quantity,validation.Order.quantity.int,validation.Order.quantity]; arguments []; default message [Quantity must be a positive integer.] 12. Batch 2, order 2 translates to the third line of MixedBag.txt, and sure enough: Winesap 56.50 2 Vanity 1200.00 1 Candles 2.25 0 13. Fix the error in the file – the correct quantity of candles is 40 – and test again, and

everything should run smoothly.

Page 162: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,
Page 163: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

CHAPTER 5

THE WEB MODULE

Page 164: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

154

OBJECTIVES

After completing “The Web Module,” you will be able to:

• Identify best practices and design patterns that have emerged in the years since Java EE was born, and explain how Spring facilitates these practices and patterns.

• Describe the lifecycle of an HTTP request/response roundtrip through a Spring web application: what components are involved in handling the request, carrying out work, presenting the next page, and handling errors.

• Refactor a traditional Java EE web application to use Spring.

• Describe the roles of key strategies in the Spring MVC cycle:

− HandlerMapping

− Controller

− ModelAndView

− ViewResolver

− View

Page 165: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

155

Servlets and JSPs: What’s Missing?

• Java servlets and JavaServer Pages (JSPs) provide the basic means of responding to HTTP requests using Java code.

• There is a good deal of overlap in their capabilities, but each is best suited to a different sort of problem:

− Servlets are Java classes and as such are strong on processing; producing HTML is possible but a bit awkward.

− JSPs are more presentation-oriented, and best practice calls for all but true presentation logic to be deployed off-page and invoked using scriptlets, standard actions or custom tags.

• Most Web applications are best developed to mix static HTML, JSPs, and servlets.

− The so-called “Model 2” architecture calls for servlets to implement business logic and then forward to JSPs to present the new information or system state as requested.

− Thus servlets and JSPs each do what they're best at doing.

• But the problem of how to coordinate these various components smoothly remains, and neither servlets nor JSP addresses this issue directly.

Page 166: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

156

The Model/View/Controller Pattern

• As introduced in Chapter 1, MVC is a way of organizing any system – we’ll apply it to web applications specifically – into major roles model, view, and controller.

• As a prescription for decoupling a complex system, MVC

succeeds based on a clear definition of dependencies:

− Both the controller and view depend on the model’s semantics.

− The model never depends on controllers and views. Think of this in terms of multi-tier architecture, too: the model may span the presentation and business tiers, or live entirely in the business tier, while the controller and view are purely presentation components.

− Neither should there be interdependencies between controllers and views.

• Observing these rules keeps a system neatly organized, allows iterative development, and the best adaptability to change.

− Especially, it facilitates many-to-many relationships: primarily from controller-to-model and view-to-model.

Controller View

Model

Page 167: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

157

The Front Controller Pattern

• A very popular Java EE design pattern is the Front Controller.

• This pattern recognizes the need for consistent pre-processing shared by many different request handlers – especially once they’ve been separated out according to MVC.

• This calls for a single controller at the front of the process – hence the pattern name – that can carry out the common pre-processing.

• This front controller is almost always linked to an application

controller, which is responsible for dispatching to individual controllers, based on request URI or parameters, session attributes, or other variables.

− Thus there is a demultiplexing of multiple request URIs to a front controller, and the application controller re-multiplexes to keep the control paths separate.

Page 168: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

158

The DispatcherServlet Class

• The entry point to the entire Spring Web module is the DispatcherServlet, which is often configured as the one and only servlet in a Spring web application.

− Find this and most of the key Spring Web types in org.springframework.web.servlet, or subpackages thereof.

− This servlet handles all control requests to the application, and then relies on a HandlerMapping implementation to dispatch to individual controllers. Does this diagram look familiar?

• There is not much public interface to show for this class.

• It handles HTTP requests via template methods doService and processRequest, which are called from its base class’ implementations of doGet, doPost, etc.

• What’s most interesting about DispatcherServlet is all the dependencies that don’t show up as public methods.

− It uses Spring IoC autowiring by type to find most of its delegate objects; we’ll see more of this throughout the chapter.

− It is also configurable through a few servlet initialization parameters – that is, via web.xml.

Page 169: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

159

A Spring Request/Response Cycle

• So already we’re getting an idea of the request/response cycle as implemented by the Spring Web module.

• We don’t have the whole story yet, but we know this much:

− DispatcherServlet asks a HandlerMapping for a Controller and

a View.

− It invokes the controller, and requested work is done there.

− It renders the view and hands it back to the user as the HTTP response.

Dispatcher Servlet

Controller

Handler Mapping

View

Request

Response

Page 170: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

160

The Strategy Pattern

• The Strategy design pattern is a basic but often overlooked technique for factoring out pieces of a complex algorithm.

• The Context object (with its remarkably apt name for what

we’re doing) has a complicated job to do.

− It could implement it, whole, but that would make for terrible maintenance characteristics.

− It could define a big pile of virtual methods – onThis and onThat – allowing subclasses to hook into its process and customize it.

− This is in fact the Template Method pattern, and it’s useful but it has its limits, especially since each unique set of customizations would require a fresh subclass.

• Strategy calls for a separate interface for each piece of the larger process that can be made reasonably discrete.

− Then subtypes can implement the strategy and plug in to the main processor.

• Does this sound familiar?

Page 171: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

161

JavaBeans as Web Components

• Spring’s Web MVC is stuffed full of Strategies.

• We’ve just seen one: the HandlerMapping, which can be implemented several different ways without even building your own subclass.

• Controller and View are strategies in themselves, at least the way Spring encapsulates them.

− Most MVC implementations take a similar approach, but it’s probably not accurate to say that Strategy is baked into MVC by definition.

• Indeed, Spring gets tremendous mileage out of this one pattern, factoring nearly all of the job of HTTP request handling into a handful of key roles and then allowing each of them to be played by a different actor.

− We’ll soon see the ViewResolver as another top-level strategy.

− There will be more to come ...

Page 172: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

162

Configuring DispatcherServlet

• Install a Spring application by the simple act of declaring the DispatcherServlet in web.xml and mapping some or all of your request URLs to it.

<servlet> <servlet-name>MyApplication</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MyApplication</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

• Well, all right, there’s a little more to do ...

− Include at least spring.jar in your WEB-INF/lib directory.

− If you want to use Spring’s JSP custom tag library, include the spring.tld in WEB-INF.

• With this in place, everything else you do will be in the “Spring domain,” so to speak, and the starting point for all such tasks is the Spring IoC container, which is specialized for web applications into a web application context.

Page 173: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

163

Web Application Contexts

• The Spring Web module relies heavily on the Core module, in particular on IoC containers.

• Every Spring web application has at least one web application context, which brings several of the behaviors we’ve already seen into a central position in the framework:

− A web application context is a bean factory – so there’s our primary IoC container capability.

− It is also a message source – so we have internationalization

− As an application context, it is hierarchical, meaning that a complex application can be organized into a tree or list of related modules.

− By itself it adds the definition of a well-known name for a root context for the application, and our primary connection to the servlet context.

• Part of learning to develop in Spring is rethinking how you do familiar things – many of which you can do directly with Spring objects instead of requiring a path to a Servlets object.

Page 174: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

164

A Minimal Spring Web Application

• As a next step in getting familiar with Spring, we’ll carry out the process of refactoring an existing, simple web application.

− The Ellipsoid application begins its life as a traditional servlet-and-JSP web application, with a JavaBean to capture useful state information and share it between components.

− We’ll gradually replace the standard Java EE workings with Spring components, and learn some new concepts along the way.

• We’ll work in Demos/SpringApp.

− The completed demo is in Examples/Ellipsoid/Web/Step4.

• Review the layout and code for the starter application.

− index.jsp presents an HTML form that gathers three dimensions of a three-dimensional ellipsoid and places a request.

− EllipsoidServlet handles the request by creating and populating a JavaBean, Ellipsoid, with request parameters. It publishes the bean at request scope and forwards to Results.jsp.

− Results.jsp reads out the information in the JavaBean, including the request parameters and additional calculated properties: volume, classification, and description.

index.jsp Ellipsoid Servlet Results.jsp

Ellipsoid

DEMO

Page 175: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

165

A Minimal Spring Web Application

1. Build the starter application and test it out: ant http://localhost:8080/Ellipsoid

DEMO

Page 176: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

166

A Minimal Spring Web Application

2. Job one is to put Spring in place, so let’s start by opening

docroot/WEB-INF/web.xml.

3. Replace the mapping to EllipsoidServlet with a mapping to the DispatcherServlet. (The URL pattern can stay, since it’s already set to *.do, and we really only have one request path anyway.)

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

DEMO

Page 177: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

167

A Minimal Spring Web Application

4. This one change puts the incoming request on a completely different track, and brings new files into play that are already completed. Look at docroot/WEB-INF/Ellipsoid-servlet.xml for starters.

− This is the primary context declaration for the web application – it plays the role of web.xml for a Spring application, using the vocabulary of the Spring beans configurations we’ve been working with so far.

− Note that the name of the file is based on the declared name of the servlet in web.xml.

<bean class="org.springframework.web.servlet.handler .SimpleUrlHandlerMapping" > <property name="mappings"> <props> <prop key="/Compute.do" > EllipsoidController</prop> </props> </property> </bean> <bean id="EllipsoidController" class="cc.math.EllipsoidController" />

− This application’s handler mapping uses an explicit map of URL keys and values that are interpreted as bean names.

− The only controller is EllipsoidController and this is mapped to the incoming /Compute.do.

DEMO

Page 178: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

168

A Minimal Spring Web Application

5. Open src/cc/math/EllipsoidController.java and see the controller code. So far, the handleRequest method doesn’t do much:

public class EllipsoidController implements Controller { public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println ("**Controller invoked.**"); return new ModelAndView (new InternalResourceView ("Results.jsp")); } }

− This ModelAndView is constructed to aggregate a prepared InternalResourceView, which is view implementation that simply wraps a browser-addressable resource within the application.

DEMO

Page 179: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

169

A Minimal Spring Web Application

6. Build, deploy, and test again to see two things.

− The results page does appear, but it shows no values, only the static labels:

− We can see that the controller was invoked by looking in the Tomcat console:

INFO: Servlet 'Ellipsoid' configured successfully ************** Controller invoked. *********** (This is the version in the example Step2.)

DEMO

Page 180: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

170

A Minimal Spring Web Application

• Spring’s authors have an unusual take on MVC, when it comes time to serve up the view: they suggest that the controller should decide on a view, and populate that view with a model.

− That is, the controller “creates a model” for the view.

− Traditionally, web MVC applications have treated the controller and view more as (perhaps unequal) partners, letting the view find the model information it would need, just as the controller would go to find the model for itself.

• The approaches are not so different in this case: the servlet was posting a bean at request scope, and this is just what Spring will do – when you pass the bean and name to a ModelAndView constructor.

7. Copy code from the servlet source file to the controller to create an Ellipsoid object and to populate it using request parameters:

public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { Ellipsoid delegate = new Ellipsoid (); delegate.setA (Double.parseDouble (request.getParameter ("a"))); delegate.setB (Double.parseDouble (request.getParameter ("b"))); delegate.setC (Double.parseDouble (request.getParameter ("c"))); return new ModelAndView (new InternalResourceView ("Results.jsp")); }

DEMO

Page 181: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

171

A Minimal Spring Web Application

8. Still, so far our ModelAndView is really just a view. Add model information using a different constructor overload:

return new ModelAndView (new InternalResourceView ("Results.jsp"), "ellipsoid", delegate);

− ModelAndView can take a prepared Map with multiple keys and values, too, but we’ll use this convenience constructor here.

9. Build and retest to see that you again have correct functionality: the controller is now creating a bean, piping input to the bean, and making the bean itself available to the view so that the expressions in Results.jsp can read out the results.

(This is the version in the example Step3.)

DEMO

Page 182: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

172

A Minimal Spring Web Application

10. Now let’s start taking advantage of a view resolver. See the rest of the context configuration file, which declares a BeanNameViewResolver. This class converts a requested view name to a View-implementing bean of a name that matches that view name.

11. See also the three beans defined to wrap three JSPs in the application, giving them simple names “Form”, “NormalResult” and “SphereResult”.

12. Modify the controller to choose between normal and sphere results – represented now as strings, not View objects – based on the results of delegate.getType:

return new ModelAndView ((delegate.getType ().equals ("Sphere") ? "SphereResult" : "NormalResult"), "ellipsoid", delegate); 13. Build and test one last time. Now the view resolver is consulted with

the string returned by the controller as part of the ModelAndView object. Try parameters you were using before, and then try using the same number for all three semi-axis lengths ...

(This is the final version in the example Step4.)

DEMO

Page 183: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

173

A Minimal Spring Web Application

• With a few code changes, we’ve put the main body of Spring MVC to work for the application – here’s our request-handling diagram again, with some new details gleaned from this demonstration:

• So HandlerMapping and ViewResolver are the next-level decision points after the servlet: one finds controllers and one finds views.

• Have you started wondering: how did the servlet find these two key objects?

Dispatcher Servlet

Controller

Handler Mapping

View

View Resolver

Request

handleRequest()

resolve ViewName()

Response

render()

getHandler()

DEMO

Page 184: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

174

Autowiring in the DispatcherServlet

• The answer harks back to our study of Spring IoC in the previous chapter: DispatcherServlet finds these two delegates through beans autowiring by type.

• This isn’t obvious, for the simple reason that the servlet isn’t declared as a bean in the configuration itself.

• Also, it does what a declared bean could not do, which is choose to autowire by type, by name, or not at all, at a property level, rather than for the object as a whole.

• See the javadoc for this class for more on which delegates are found by what means – but an incomplete list, including several concepts we’ve yet to study, is here:

− A HandlerMapping is wired by type

− A ViewResolver is wired by type

− A MessageSource is wired by the name “messageSource” – actually this is the web application context, not the servlet itself, doing the matching

− A HandlerExceptionResolver is wired by type

− A MultipartResolver is wired by the name “multipartResolver”

− A LocaleResolver is wired by the name “localeResolver”

− A ThemeResolver is wired by the name “themeResolver”

Page 185: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

175

The HandlerMapping Interface

• We’ve already seen the most important job that HandlerMapping does, which is help the dispatcher servlet decide on a controller for a given request.

• There is (how many times will we say this?) more to the story.

• The full responsibility of a HandlerMapping is to derive a HandlerExecutionChain.

public interface HandlerMapping { public HandlerExecutionChain getHandler (HttpServletRequest request); }

− This, in turn, navigates to one handler and any number of HandlerInterceptors.

− (We’re still in org.springframework.web.servlet for all three of these types.)

• Interceptors implement the Intercepting Filter pattern for

Spring; they are loosely analogous to servlet Filters.

− We’ll consider interceptors in more depth later in the course.

Page 186: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

176

The Controller Interface

• It all starts with the HandlerMapping ... but most of the real action is in the Controller.

• Though any object can technically be a Spring request handler, for HTTP requests all controllers will be implementations of the Controller interface.

− All the controller types below are from the package org.springframework.web.servlet.mvc:

Page 187: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

177

Controller Responsibilities

• The Spring controller has an outsized role compared to the model and view: it really manages the remainder of the request-handling process.

• The basic job of a controller is to carry out the requested work and to serve up a view and a map of objects which the dispatcher servlet should make available to that view during its rendering.

• AbstractController is a convenient base type for controllers playing just this simple role.

• Other subtypes define – and then meet – additional responsibilities:

− MultiActionController does additional dispatching to a delegate object, with additional strategy choices for deciding what methods to call for what request URIs and query strings.

− AbstractCommandController formalizes the use of a command object: creating this JavaBean during request handling, binding request parameters to it, calling configured validators, and then making it available to controller and view components.

− AbstractFormController goes further and encapsulates some of the concepts of the HTML form itself, managing form input, processing, and even redirecting flow back to the form when errors occur.

• We’ll consider these different controller types in two later chapters.

Page 188: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

178

The ModelAndView Class

• ModelAndView is a simple aggregation of a View object and a “model” – which in this context means a map of keys and objects that might be useful to view rendering, and not the overall state model of the MVC application.

public class ModelAndView extends Object { public ModelAndView (View view); public ModelAndView (View view, Map model); public ModelAndView (View view, String oneKey, Object oneValue); public ModelAndView (String viewName); public ModelAndView (String viewName, Map model); public ModelAndView (String viewName, String oneKey, Object oneValue); ... }

• Overloads of its constructor allow for various usages:

− Provide a View instance or a name to be passed to a ViewResolver.

− Provide no model, a single key/value pair (surprisingly useful and common), or a full-fledged map.

• Its public methods are mostly called by framework code, so we won’t delve into those too deeply.

Page 189: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

179

The View Interface

• A View is simply a component that can render a response in the appropriate content type.

• There are over two dozen view types implemented in Spring.

• Just a handful support most Spring development – here are some of the most common types:

Page 190: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

180

The ViewResolver Interface

• Once a controller has done its work, it will report back to the dispatcher servlet with a ModelAndView object.

• For complex applications, this will usually carry the name of a desired view for the servlet to render to the HTTP response.

• Translating, or resolving, this name to an actual View object is the responsibility of a configured ViewResolver:

public interface ViewResolver { public View resolveViewName (String name, Locale locale); }

− The one method on this interface, resolveViewName, illustrates the simplicity of the job description.

− It also points up one of the more compelling reasons to use view resolvers, which is the built-in internationalization support.

− If a controller builds or finds its own view, any i18n support will have to come from the controller’s own logic – and that gets old pretty quick when you’re writing tens or scores or hundreds of controllers.

Page 191: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

181

Online Banking

• Let’s use another example application as a way of reviewing the control paths that make Spring’s MVC work.

− We’ll trace the flow of control all the way from the receipt of the incoming HTTP request around to the rendering of the response.

• See Examples/Bank/Web for a two-page web application that allows the user to make transactions on a preconfigured bank account:

• From window.jsp the user actually has three options:

− Deposit and Withdraw buttons request the Transact.do URL.

− A link to close this account requests Close.do.

window.jsp Teller

closed.jsp

Account

Manager

Transact.do

Close.do

EXAMPLE

Page 192: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

182

Online Banking

• Let’s build and run the application first – so we know what it does, before asking how it does it.

− Run ant and visit the following URL: http://localhost:8080/Bank

− Make a deposit ...

− ... and close the account:

EXAMPLE

Page 193: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

183

Online Banking

• Consider a request to make a deposit – what happens from the moment the user clicks the Deposit button?

1. The server receives an HTTP request for this resource: http://localhost:8080/Bank/Transact.do 2. This is fielded by the web container, which (a) determines the correct

web application by searching its index of deployed applications and their context URLs, and (b) consults the web.xml file for a possible servlet mapping.

<servlet> <servlet-name>Bank</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Bank</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> 3. The application says all requests ending in .do go to the Spring

DispatcherServlet, and the container dispatches the request there and waits for request handling and response rendering.

4. The DispatcherServlet has been initialized based on the servlet name given by web.xml and so knows to configure itself from a file Bank-servlet.xml.

EXAMPLE

Page 194: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

184

Online Banking

5. Based on those bean declarations, it will now carry out the process diagrammed earlier:

6. So, first it looks for a HandlerMapping, and finds one: <bean class="org.springframework.web.servlet.handler .SimpleUrlHandlerMapping" > <property name="mappings"> <props> <prop key="/Approach.do" >Teller</prop> <prop key="/Transact.do" >Teller</prop> <prop key="/Close.do" >Manager</prop> </props> </property> </bean>

Dispatcher Servlet

Controller

Handler Mapping

View

View Resolver

Request

handleRequest()

resolve ViewName()

Response

render()

getHandler()

EXAMPLE

Page 195: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

185

Online Banking

7. The SimpleUrlHandlerMapping tells the servlet that a request to Transact.do should be handled by an instance of the Teller bean:

<bean id="Teller" class="cc.bank.Teller" autowire="byType" /> 8. Thus comes a call to the handleRequest method on cc.bank.Teller.

This singleton bean has a dependency on a bank account (specifically, Spring sees the method setAccount) auto-wired to the only Account instance in the configuration:

<bean class="cc.bank.CheckingAccount" > <constructor-arg type="double" value="500" /> </bean> 9. handleRequest then looks at request parameters and either deposits

or withdraws the requested amount: double amount = Double.parseDouble (amountParam); if (request.getParameter ("deposit") != null) account.deposit (amount); if (request.getParameter ("withdraw") != null) account.withdraw (amount); 10. Then it returns instructions to the DispatcherServlet in the form of a

ModelAndView object that says two things: (a) put a bean called “account” at request scope so the view can see it, and (b) resolve to a view identified as “window”.

return new ModelAndView ("window", "account", account);

EXAMPLE

Page 196: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

186

Online Banking

11. The DispatcherServlet finds (actually, has already found) its ViewResolver in the configuration:

<bean class="org.springframework.web.servlet.view .InternalResourceViewResolver" > <property name="prefix" value="" /> <property name="suffix" value=".jsp" /> </bean> 12. The InternalResourceViewResolver maps the view name to the

location of an internal resource: the window.jsp.

13. It wraps this resource in an InternalResourceView object and hands that back to the DispatcherServlet.

14. The DispatcherServlet then asks this view object to render the HTTP response – this occurs as usual for a JSP, no real Spring intervention in the process – and then returns control to the web container.

EXAMPLE

Page 197: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

187

Wholesale Spring

Suggested time: 60 minutes

In this lab you will implement a partial version of the Wholesale application, now retooled for the web. This will provide some challenging exercise in building Spring applications from scratch; it’s not a refactoring exercise, as we’ve had plenty of those by now. In general this case study will offer opportunities to build new functionality “the right way” right off the bat.

The domain model is largely intact from earlier chapters – a few tweaks – and for this exercise you’ll implement a simple page flow that will demonstrate end-to-end connectivity in processing prepared sales feeds at the direction of the operator.

Detailed instructions are found at the end of the chapter.

process.jsp ProcessOrders processed.jsp

LAB 5A

Page 198: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

188

Integrating XSLT

Suggested time: 30 minutes

In this lab you will improve on the response provided by the Wholesale application after it processes a batch of orders. We have a good XSLT transform already defined that can produce HTML from the XML sales report. What we need to do is integrate this XSLT into a Spring request/response cycle.

It turns out there’s a View class for that! You’ll instantiate XsltView and inform it with the XML source and XSLT transform locations, resulting in a modified page flow:

Detailed instructions are found at the end of the chapter.

process.jsp ProcessOrders SalesReport.xsl

LAB 5B

Page 199: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

189

SUMMARY

• The Spring Web module is meant to simplify the development of complex web applications – but it is quite a complex system in and of itself.

• Still, there is an elegance to the kernel of the module: the request-handling process carried out by the dispatcher servlet.

− It’s extrapolated from MVC, with Controller and View interfaces at the heart of the system.

− Each of these actors is chosen by an agent: HandlerMapping for Controller, ViewResolver for View.

− Each of these four roles is plugged in to the dispatcher servlet via the Strategy design pattern.

− Each has multiple subtypes, which can be mixed, matched, combined, and extended.

• The whole system sits on top of one or more Spring IoC containers.

− Bean configurations, autowiring, dependencies, and collections – all these Core techniques are now folded into the declarative side of Spring Web development.

Page 200: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

190

Wholesale Spring

In this lab you will implement a partial version of the Wholesale application, now retooled for the web. This will provide some challenging exercise in building Spring applications from scratch; it’s not a refactoring exercise, as we’ve had plenty of those by now. In general this case study will offer opportunities to build new functionality “the right way” right off the bat.

The domain model is largely intact from earlier chapters – a few tweaks – and for this exercise you’ll implement a simple page flow that will demonstrate end-to-end connectivity in processing prepared sales feeds at the direction of the operator.

Lab workspace: Labs/Lab5A

Backup of starter code: Examples/Wholesale/Web/Step1

Answer folder(s): Examples/Wholesale/Web/Step2

Files: docroot/WEB-INF/web.xml docroot/WEB-INF/Wholesale-servlet.xml src/cc/sales/web/ProcessOrders.java (to be created)

Instructions:

1. As always, let’s start with the deployment descriptor. Open web.xml and declare the DispatcherServlet with the name “Wholesale”. Declare a mapping to this servlet for all requests of the pattern *.do.

2. Open Wholesale-servlet.xml, and see that many of the bean definitions from previous exercises have been carried over to this starter code. Now that we’re in a web context – and might be deployed to many different directories in different scenarios – both the fulfillment engine and the orders DAO require some flexibility in their paths for persistent files. This is the meaning of the ${env.CC_MODULE} phrases you see in these configurations: the syntax is borrowed from Ant, and the Java classes themselves resolve these phrases to the actual value of the CC_MODULE environment variable at runtime.

3. Declare a SimpleUrlHandlerMapping for your application. Set up one mapping, from the URL /processOrders.do to the bean name “processOrders”.

process.jsp ProcessOrders processed.jsp

LAB 5A

Page 201: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

191

Wholesale Spring LAB 5A

4. Define your controller bean, with that same name, and class cc.sales.web.ProcessOrders.

5. Declare an InternalResourceViewResolver with an empty prefix and a suffix of “.jsp”.

6. Declare your message bundle. The file already exists – WEB-INF/classes/messages.properties. We haven’t covered this process yet; the declaration you want is shown here:

<bean id="messageSource" class= "org.springframework.context.support.ResourceBundleMessageSource" > <property name="basename" value="messages" /> </bean> 7. Validate your context configuration file, and fix any validity errors.

8. Take a look at docroot/process.jsp and see what sort of request you’re about to get: the page holds a multi-select list of filenames and will submit a request parameter feeds for each value the user chooses.

9. Now create your controller class, in src/cc/sales/web/ProcessOrders.java. Make the class implement the Controller interface and stub out your handleRequest method. You’ll want to import the cc.sales package for general use, as well.

10. Declare private fields referring to a Fulfillment object and an OrderDAO, and define mutator methods for each, setEngine and setDatabase.

11. Implement your handleRequest method: start by declaring a local variable orders and initializing it to a new ListOfBatches. Then call setFeeds on the bean, passing the array of values retrieved by calling request.getParameterValues with the parameter name “feeds”.

12. Call orders.getBatches with the database fields as a parameter. This will load in and return your order data.

13. Call engine.fulfill, passing the result of your call to getBatches as the first argument. This second argument gives the resulting sales file a name unique to the calling thread; a good way to generate this is to call System.currentTimeMillis, and then use Long.toString to convert that value to a string.

14. The result of this call to fulfill is a double representing total sales. Create a ModelAndView, passing three arguments: “processed” as your base view name, “totalSales” as a model key, and this total-sales value from the fulfill call.

15. Return this ModelAndView from your method.

16. Okay, what do you think – are you ready to build and test?

Page 202: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

192

Wholesale Spring LAB 5A

17. There is one thing missing: how will your engine and database dependencies be satisfied?

You could explicitly configure values for each property in the context configuration. But this is a good opportunity to use autowiring, since both properties are of distinctive types that should be preserved as singletons. Simply set autowire to “byType” on your “processOrder” bean.

18. Now, do build and test. The ant command will trigger the whole build process, and will deploy the application to Tomcat. If Tomcat is not running, start it, either before or after your Ant build.

19. Everything should now be in place; if you visit the following URL in your browser you should be able to select one or more sales feeds, click Process, and see the simple confirmation page in your browser.

http://localhost:8080/Wholesale/process.jsp

Page 203: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

193

Integrating XSLT

In this lab you will improve on the response provided by the Wholesale application after it processes a batch of orders. We have a good XSLT transform already defined that can produce HTML from the XML sales report. What we need to do is integrate this XSLT into a Spring request/response cycle.

It turns out there’s a View class for that! You’ll instantiate XsltView and inform it with the XML source and XSLT transform locations, resulting in a modified page flow:

Lab workspace: Labs/Lab5B

Backup of starter code: Examples/Wholesale/Web/Step2

Answer folder(s): Examples/Wholesale/Web/Step3

Files: docroot/SalesReport.xsl src/cc/sales/Fulfillment.java src/cc/sales/web/ProcessOrders.java

Instructions:

1. The first step in getting the XSLT transformation activated is to make the source XML available through the controller. Right now the Fulfillment.fulfill method returns the raw sales number as a double. Refactor this: change the method to return the output filename instead: this means changing the method signature and returning filename instead of totalSales.

2. In ProcessOrders.handleRequest, after initializing the orders variable, declare a new local variable view and initialize it to a new XsltView. (Import this from org.springframework.web.servlet.view.xslt.)

3. Call view.setUrl, passing “SalesReport.xsl”.

process.jsp ProcessOrders SalesReport.xsl

LAB 5B

Page 204: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

194

Integrating XSLT LAB 5B

4. XSLT views need visibility to the application context, in a way that simple internal-resource views do not. (XSLT has broader general requirements than just loading a single file – there are at least two files to load, and both the source document and the transform can call for additional resources, including the use of relative paths.) So you’ll first need to declare a web context listener, back in web.xml:

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

This is stock code for a Spring web.xml file, right along with the servlet and mapping.

5. Now get the context reference, using Spring utility classes – here’s the incantation: view.setApplicationContext (WebApplicationContextUtils.getRequiredWebApplicationContext (request.getSession ().getServletContext ()));

You’ll need to import org.springframework.web.context.support.WebApplicationContextUtils.

6. Remove the wrapping of a new ModelAndView around the call to engine.fulfill – but leave that method call intact, including its arguments.

7. Now that this method returns a filename, you can instead pass it to the constructor for a new FileReader. Pass that reader to a new BufferedReader, and use that to initialize a new local variable in.

8. Now you’re ready to return a ModelAndView. You have a view, which is primed with the XSLT document’s URL, and an application context to load other resources as necessary. This view will look in the model map for one of a few object types, one of which is a Reader, and finding that object it will treat it as the source for the transform. So: create a new ModelAndView, passing view, “sourceKey”, and in as the constructor arguments, and return that new object.

9. Now you have a new page flow, as your controller is ignoring the view resolver and returning an XSLT-based view:

Page 205: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 5

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

195

Integrating XSLT LAB 5B

10. Build and test: you should see your form submission followed directly by the formatted HTML report:

Page 206: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,
Page 207: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

CHAPTER 6

THE PERSISTENCE TIER

Page 208: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

198

OBJECTIVES

After completing “The Persistence Tier,” you will be able to:

• Explain the usefulness of the Data Access Object design pattern.

• Implement JDBC DAOs using Spring’s support classes and templates.

• Describe the Spring approach to unifying transaction control.

• Implement declarative transactions for a Spring Web application.

Page 209: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

199

The Data Access Object Pattern

• The Data Access Object, or DAO, is a category of OO class that assumes the responsibility for translating state between a transient object and a persistent record – typically in a relational database.

− We want to keep this logic separate from business logic – this is just as important as separating presentation logic from business logic, although it guards against different threats.

• The solution can be as simple as defining a DAO encapsulation, but it is usually a little more complicated:

Page 210: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

200

The Data Access Object Pattern

• DAOs can also enhance scalability over large data sets, because they offer a many-to-many relationship between transient and persistent data.

− A large set of data instances can live in the persistent store.

− A smaller set of transient incarnations can be used to represent the data that is needed in the moment; even if this winds up spanning the full persistent store, it improves performance by recycling the transient objects from a pool.

• DAOs may also implement caching, or work as adapters to external caching strategies.

• Most prevalent implementations of the DAO pattern target relational databases:

− JDBC-based DAOs – the “hand-made” solution, often built from scratch per application

− Enterprise JavaBeans’ container-managed persistence

− Object/relational mapping tools

• But the pattern maps neatly to XML, text files, serialized objects, and so forth.

• It also offers the advantage of a consistent interface to different data formats, so that application code might be working with file-backed objects or a full-featured relational database, with no recoding necessary.

Page 211: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

201

Spring DAO Implementations

• Spring embraces the DAO pattern heartily.

• It defines several central encapsulations that allow the application to avoid dependencies on any specific DAO solution.

− A DaoSupport class forms the basis of a hierarchy whose subclasses provide support specific to JDBC, Hibernate, etc.

− A consistent exception hierarchy makes it possible to handle data-access errors in a consistent fashion – again, avoiding lock-in to a particular DAO strategy.

• It provides impressive libraries of code to support DAO implementation in various styles:

− JDBC

− Hibernate

− JDO

− TopLink

Page 212: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

202

The DaoSupport Hierarchy

• The conceptual foundation of Spring’s DAO support is a tree of classes based in org.springframework.dao.support.DaoSupport:

• This is intended to abstract the very basics of DAO behavior so that applications can interact with a DAO layer while staying neutral on DAO strategy and tools.

• These classes may or may not be part of a practical solution: frankly, Spring IoC has gotten so good that it’s common enough to declare all the concrete types under various application-specific DAO interfaces, so that the services of DaoSupport & Company may not be required.

Page 213: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

203

The DataAccessException Hierarchy

• It wouldn’t do for applications to code to a unifying DAO API, only to be forced to handle exception types unique to a specific DAO implementation.

• So Spring provides a unifying exception library as well:

• Spring-supported API-specific exceptions can be converted to exceptions in this library and re-thrown.

− This is done differently for different DAO implementations.

− The result is that many checked exceptions are converted to unchecked ones – note RuntimeException at the root of the tree.

− It is Spring’s philosophy that exceptions thrown from persistence methods are almost always fatal, and so should fall through easily.

Page 214: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

204

JDBC DAOs

• For all but the simplest data models, writing “raw” JDBC code to build a DAO layer is a grueling task.

− JDBC wraps SQL strings, and simplifies some tasks, but one is basically still working with a string literal – which can’t be checked for types or validated in any way prior to runtime.

− There is a tremendous amount of boilerplate coding involved in even a simple SQL query: getting and closing connections and statements, exception handling, closing the result set, etc.

− JDBC offers no support for O/R mapping, and the devil is very much in the details there.

• Spring can solve the middle problem! A JdbcTemplate class provides excellent utility methods that do nearly all the boilerplate stuff around your simple SQL queries and updates.

• It can also take a bite out of the other two:

− It facilitates the use of prepared statements, and will take much of the string-building work off your hands, doing some type checking and type detection along the way.

− It also defines callbacks such as RowMapper, a poor-man’s O/R interface allowing utility methods to jump all the way from SQL inputs to Java object outputs.

• Also, Spring IoC fits naturally to the problem of configuring data sources and other JDBC infrastructure, to avoid hard-coding database URLs and user credentials.

Page 215: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

205

The JdbcTemplate Class

• org.springframework.jdbc.core.JdbcTemplate boasts far too many overloads of its main utility methods to dig into all of them – but here’s a sampler:

public class JdbcTemplate { public JdbcTemplate (DataSource source); public int[] batchUpdate (String[] sql); public int execute (String sql); public List query (String sql, RowMapper mapper); public List query (String sql, Object[] args, RowMapper mapper); public List query (String sql, Object[] args, int[] argTypes, RowMapper mapper); public int queryForInt (String sql); public Object queryForObject (String sql, Class requiredType); public int update (String sql); }

• Initialize a JdbcTemplate based on any JDBC 2.0 DataSource.

− Typically you will declare your data source in a bean context, and then inject it into a JdbcTemplate that you also declare.

− If you don’t have a DataSource implementation handy, Spring offers DriverManagerDataSource to adapt any JDBC 1.0 driver.

Page 216: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

206

The RowMapper Interface

• To convert JDBC ResultSet rows into objects of your desired type during its various query operations, JdbcTemplate relies on a dead-simple callback interface, RowMapper:

public interface RowMapper { public Object mapRow (ResultSet rs, int row) throws SQLException; }

• Subclasses are generally dedicated to specific data types.

− mapRow is typically implemented to create a new object of that data type, passing values from the current row in the ResultSet either as constructor arguments or to mutator methods.

− The ResultSet will already be “primed” to the relevant row.

− There is no need to seek to the row based on the row argument; this is provided as additional information that may be useful in some scenarios, but it is more often ignored.

Page 217: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

207

MySQL

• For this chapter’s exercises we need an RDBMS, and MySQL has been included with the lab software.

• Start the MySQL server now, by running the following command from c:/Capstone/Tools/MySQL5.0/bin:

mysqld

− Note that the console you use to run this command will appear to hang; this is the MySQL daemon process listening for connections at its default port 3306.

• When you want to shut the server down again, run this prepared script from the same directory:

shutdown

Page 218: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

208

A Wholesale Database

• Examples/Wholesale/Web/Step10 has been beefed up considerably, with a relational database ready to hold sales feeds.

• Scripts in the data directory will create or remove the database – here’s create-db.sql:

create database Wholesale; use Wholesale; create table ordr ( ordr_ID integer not null auto_increment, feed varchar(32) not null, product varchar(32) not null, price double not null, quantity integer not null, primary key (ordr_ID), unique key (feed, product) ) engine=InnoDB;

• Ant targets create-DB and remove-DB send these scripts to the running MySQL server.

− Create the database now: ant create-DB create-DB: Creating database ... Executing file: C:\Capstone\Spring\Examples\Wholesale\Web\Step10 \data\create_db.sql 3 of 3 SQL statements executed successfully

EXAMPLE

Page 219: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

209

A Wholesale Database

• The application now sports a JDBC DAO.

• See docroot/WEB-INF/Database.xml.

− It uses MySQL’s own DataSource implementation for the Wholesale database:

<bean class= "com.mysql.jdbc.jdbc2.optional.MysqlDataSource" > <property name="url" value="jdbc:mysql://localhost/Wholesale" /> <property name="user" value="root" /> <property name="password" value="" /> </bean>

− Spring also provides a DriverManagerDataSource that can adapt a DriverManager, for products that don’t have native DataSource implementations of their own.

− A JdbcTemplate is auto-wired to this data source: <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" autowire="constructor" />

EXAMPLE

Page 220: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

210

A Wholesale Database

− The DAO itself is auto-wired to the template: <bean id="database" class="cc.sales.db.OrderDAOImplJDBC" autowire="byType" />

• The source code for the DAO is in src/cc/sales/db/OrderDAOImplJDBC.java:

public List<Order> load (String feedName) { return (List<Order>) template.query ("select * from ordr where feed = '" + feedName + "'", orderMapper); }

− The load method uses the JdbcTemplate.query method on a simple SQL string.

− It provides a RowMapper to convert rows into Order objects: private static class OrderMapper implements RowMapper { public Object mapRow (ResultSet rs, int row) throws SQLException { return new Order (rs.getString ("product"), rs.getDouble ("price"), rs.getInt ("quantity")); } } ... private static final RowMapper orderMapper = new OrderMapper ();

EXAMPLE

Page 221: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

211

A Wholesale Database

− The save method takes advantage of Spring’s ability to replace parameters in a prepared statement, and to provide the right syntax for each value based on its reflected type.

public void save (List<Order> feed, String feedName) { String sql = "delete from ordr where feed = '" + feedName + "'"; template.update (sql); sql = "insert into ordr " + "(feed, product, price, quantity) " + "values (?, ?, ?, ?)"; for (Order order : feed) { Object[] args = { feedName, order.getProduct (), order.getPrice (), order.getQuantity () }; template.update (sql, args); } }

EXAMPLE

Page 222: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

212

A Wholesale Database

• The project has also been enhanced with build and run scripts like the ones we were using for standalone applications in earlier chapters.

• The Controller class in this case does more than just load and exercise the JavaBeans, though: it builds the standard data model for the application, using the DAO to populate the new database.

OrderDAOImplJDBC DAO = (OrderDAOImplJDBC) beanFactory.getBean ("database"); List<Order> batch1 = new ArrayList<Order> (); batch1.add (new Order ("Macoun", 56.5, 6)); batch1.add (new Order ("Winesap", 48, 6)); batch1.add (new Order ("Baldwin", 50.2, 4)); DAO.save (batch1, "Apples");

EXAMPLE

Page 223: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

213

A Wholesale Database

• Run this application now: build run

• Use the mysql utility to check the outcome: c:\Capstone\Tools\MySQL5.0\bin\mysql --user=root mysql>use Wholesale; Database changed mysql>select * from ordr; +-----+-------------+-------------+-------+------+ | 1 | Apples | Macoun | 56.5 | 6 | | 2 | Apples | Winesap | 48 | 6 | | | | | | | | | | | | | | 13 | MixedBag | Vanity | 1200 | 1 | | 14 | MixedBag | Candles | 2.25 | 40 | +-----+-------------+-------------+-------+------+ 14 rows in set (0.02 sec) mysql>exit;

EXAMPLE

Page 224: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

214

Integrating the Wholesale Database

Suggested time: 30 minutes

In this lab you will integrate the new database and DAO layer into the Wholesale web application. Actually, integration will be a snap: you’ll just change the declaration for the DAO in the context configuration. But the DAO also needs more code – load and save are good, but the web application also requires a getList method, and generally for the DAO to plug into the OrderDAO interface that’s used throughout the rest of the code base.

Detailed instructions are found at the end of the chapter.

LAB 6

Page 225: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

215

Object/Relational Mapping

• The process of O/R mapping is certainly more complicated than implementing RowMapper.

• Table-to-class mapping is the basis for everything else.

• But the complicated part is in managing relationships.

− Databases are relational, after all.

− But they manage relationships with foreign keys.

− Object-oriented languages use object references.

• It’s more than just implementation technique, too: there is a basic difference in navigability:

− RDB foreign keys make it easy to navigate from the “many” side of a relationship to the “one” side.

− OO languages allow that classes could be implemented to allow navigation from either side, but going from the “one” to the “many” is much more common than the other way around.

• Many-to-many relationships in OO models actually require additional “link” tables in the database.

• Database constraints may be mappable to the object model, or not so much.

− Java Maps can imitate RDB primary keys for most purposes.

− But what about an overlaid unique key? A stored procedure? A trigger? Etc.

Page 226: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

216

Hibernate

• There are a handful of high-quality O/R mapping tools in circulation.

• One that has been steadily gaining adherents is Hibernate.

• Hibernate tackles the general problem of Java object persistence in a way that’s very much in harmony with Spring’s approach to other Java problems.

− That is, it uses a ton of XML!

− Hibernate declares mappings between Java classes and RDB tables in mapping files – these are XML files according to a Hibernate mapping schema:

<hibernate-mapping> <class name="cc.sales.Order" table="ordr"> <id name="ID" column="ID" type="java.lang.Long" access="field" > <generator class="identity" /> </id> <version name="version" access="field" column="version" type="integer"/> <property name="product" column="product" type="java.lang.String" access="field" not-null="true" /> ...

− Relationships are called out in the mapping file(s) for one or both of the participants.

− A master configuration file enumerates the object mappings and declares global facts including session management and caching policies.

Page 227: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

217

Hibernate DAOs

• Spring brings some of the same enhancements and simplifications to Hibernate coding that it offers for JDBC.

• Hibernate should be simpler than JDBC to start with, thanks to the XML-based mappings.

• But it’s still surprisingly code-intensive, for two main reasons:

− The session is to Hibernate what the connection is to JDBC: that is, an important, useful, essential object, and also a major headache.

− Typical Hibernate code is lousy with try/catch/finally blocks; in fact more than half the code in most pure-Hibernate DAOs is exception-handling code.

• Spring relieves the individual DAO of both of these boilerplate coding tasks, and adds the usual dose of IoC medicine as well.

• It’s beyond our scope to dig into Hibernate DAO implementation, but here are some very loose metrics:

− A JDBC DAO class with Spring will often be smaller than a Hibernate DAO without it.

− Spring/Hibernate DAOs are somewhere between 50% and 75% smaller than their pure-Hibernate counterparts, depending on who you talk to.

Page 228: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

218

Transaction Control in J2EE

• Traditionally, Java developers have been faced with some unpleasant choices when it comes time to implement transaction control for their applications.

− Direct transaction management via JDBC is clunky, nearly unmaintainable, and can’t support multiple databases effectively.

− The Java Transactions API, or JTA, offers support for distributed transactions (i.e. multiple databases), but is even less appealing as an API and carries considerable weight, including a semi-dependency on JNDI as a way of publishing and sharing transaction contexts.

• J2EE’s primary solution has been container-managed transactions in EJB containers.

− This is essentially a JTA solution, but CMT hides the JTA details.

− What’s good about CMT is that it recognizes that transactionality is a cross-cutting concern, a general feature common to otherwise very different business objects.

− In fact much of EJB’s deployment descriptor vocabulary can be seen as an early attempt at aspect-oriented programming: declarative development in general is about identifying generic features that can be implemented on behalf of a class, rather than the class having to seek out and call a reusable utility on its own.

− What’s not so good about CMT is that it requires an EJB container, and hence a full-blown J2EE application server, plus all the coding headaches of EJB.

Page 229: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

219

Spring’s Transaction Management

• Spring takes the basic concept of declarative transactions and runs away with it – it leaves the weight of EJB behind.

− It’s Spring’s philosophy all over again, that ordinary Java beans should enjoy the declarative instantiation, management, services, lifecycle, and context traditionally reserved for specialized stereotypes such as servlets and EJBs.

− Spring looks at declarative transactions and asks, “Why can’t ordinary Java classes have those?”

• The building blocks of transaction management in Spring are:

− A transaction manager, of which Spring offers many off-the-shelf implementations

− A data source or other transactional resource

− Transaction advice attached to one or more transactional resources, spelling out transaction requirements and attributes

• These can all be supplied by declarative or programmatic means.

− A completely declarative approach is most common.

• Spring’s transaction model does not require the services of a heavyweight container, as EJB’s model does.

• However, it cannot support distributed transactions.

− This compromise is completely acceptable for most applications, which will only use a single database anyway.

Page 230: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

220

Declarative Transactions

• Steps to implementing transactional behavior for your Spring application are as follows.

− We’ll speak the language of JDBC here, but all the following concepts map one-for-one to other persistence techniques, including O/R mapping tools.

1. Declare your data source as a global bean – we’ve seen an example of this already.

2. Declare a transaction manager and inject the data source into it. <bean id="transactionManager" class="org.springframework.jdbc.datasource .DataSourceTransactionManager" > <property name="dataSource" ref="dataSource" /> </bean> 3. For each transactional class or method, declare transactional advice

and attach that advice to the class or method.

• There are several alternatives for this last piece.

• This is the aspect-oriented part of the puzzle, and AOP practice for Java is evolving rapidly.

− The longest-standing approach uses Spring AOP.

− If coding in Java 5, you can use annotations.

− There is also support for AspectJ.

Page 231: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

221

Spring AOP vs. Annotations

• As we’ve discussed in the previous chapter, Spring AOP and Tomcat don’t mix so well.

− The CGLIB code generator eventually drains the “PermGen” memory space that a Java VM expects to be reserved for ordinary, i.e. static, class definitions.

− Successive redeployments to Tomcat will continually re-generate AOP classes, and gradually the heap space will be drained.

− This is a non-starter for most professional situations.

• AspectJ doesn’t suffer this embarrassment, but it’s not as naturally bound to Spring, either.

• The Java-5.0 annotation is actually the new kid on the block, but it’s a proven, portable, and well-tested feature of the language.

− The downside is that annotations live in Java source files, and so can’t be modified independently of the class.

− Generally this is a significant caution regarding the use of annotations, but they have their place, and transactions are a good example of appropriate use.

− Transaction attributes, once declared, are not usually volatile, or if they are changing it’s usually in concert with significant code changes anyway.

− Spring’s @Transactional annotation is dead-simple to use, and does have the advantage of making it easy to see in source code and javadoc what interfaces, classes, and methods offer which transactional characteristics.

Page 232: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

222

The @Transactional Annotation

• org.springframework.transaction.annotation.Transactional can be applied to classes, interfaces, and methods.

public interface Transactional extends Annotation { public Propagation propagation (); public Isolation isolation (); public int timeout (); public boolean readOnly (); public Class[] rollbackFor (); public String[] rollbackForClassName (); public Class[] noRollbackFor (); public String[] noRollbackForClassName (); }

− As you can see, it can support precise definitions of transactional behavior, including isolation level and propagation characteristics (e.g. what happens if a transaction is already in force).

− The rollbackFor array allows you to declare what sorts of exceptions should trigger rollbacks. The default is to roll back on any runtime exception.

• Spring does bend the rules a bit regarding inheritability with this annotation.

− It is @Inherited, but Spring also respects inheritance of transactionality under interfaces, and for individual methods; this is inconsistent with standard annotation processing.

− This is a minor wrinkle, but it can confuse other annotation processors such as documentation generators.

Page 233: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

223

Enforcing Transactions

• We’ll conclude our study of persistence tiers in Spring applications by adding transaction support to the Wholesale application.

− Do your work in Demos/Transactions.

− The completed demo is in Examples/Wholesale/Web/Step12.

1. First, test the transactional behavior of the starter application. You may have noticed that the database includes an overlaid uniqueness constraint for the ordr table: duplicate listings of a given product are not allowed within a feed. That is, no two rows can have the same feed name and product name.

DEMO

Page 234: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

224

Enforcing Transactions

Build and deploy; edit one of the feeds by changing the second item to have the same product name as the first, then click Done:

DEMO

Page 235: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

225

Enforcing Transactions

2. You get an error as you run afoul of this constraint. But what’s more interesting is what’s happened to the data for that feed. Go to feeds.jsp again, and edit the same feed. See that all the feed contents except for the first order are now gone. They missed the boat! When the error occurred, the process was simply terminated, with one order in, a bad one rejected, and the rest of the order simply vanished.

3. Open docroot/WEB-INF/Database.xml, and notice that a second XML namespace is now supported for this document. This is the Spring transactions schema, with the namespace URI:

http://www.springframework.org/schema/tx 4. Declare a transaction manager for the web application – the

autowiring will seek out and connect to the data source that’s already declared:

<bean id="transactionManager" class="org.springframework.jdbc.datasource .DataSourceTransactionManager" autowire="byType" /> 5. And now for the magic words: “annotation-driven.” Declare this one

feature as follows, and it enables Java-5.0 transaction annotations throughout the application:

<tx:annotation-driven />

DEMO

Page 236: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

226

Enforcing Transactions

6. Now, in src/cc/sales/OrderDAO.java, import the @Transactional annotation:

import org.springframework.transaction .annotation.Transactional; 7. ... and declare it for all three methods, as in: @Transactional public void save (List<Order> feed, String feedName) throws Exception; 8. Build the application and re-populate the database: ant build run 9. Test the same use case, creating a duplicate product in one of the

existing feeds. You’ll get the same error page back, but when you visit that feed again, you’ll see clearly that the transaction was rolled back: none of your edits were committed to the database, and so not only integrity but consistency has been preserved.

DEMO

Page 237: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

227

SUMMARY

• Spring does not re-invent the wheel in supporting persistence.

− There are good persistence solutions out there already.

• But Spring is well positioned to add great value to many proven object-persistence technologies.

− Spring IoC hits the nail right on the head when it comes to keeping database deployment specifics out of Java code: these are perfect examples of injectable dependencies.

− Spring goes the extra mile in taking a lot of grunt work off of your hands: especially initialization and cleanup tasks.

− By parameterizing some of the more common algorithms with callback interfaces such as RowMapper, Spring templates can reduce those operations to nearly trivial implementations for the application programmer.

− They’ve also placed a high priority on convenience, with no method overload spared, for example in JdbcTemplate.

• Spring’s transaction support strikes a nice balance between feature set and simplicity.

− The major simplifying assumption is that there’s a single database.

− Thus the lightweight Spring container can support declarative transactions – just like the big boys! – and with less work.

Page 238: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

228

Integrating the Wholesale Database

In this lab you will integrate the new database and DAO layer into the Wholesale web application. Actually, integration will be a snap: you’ll just change the declaration for the DAO in the context configuration. But the DAO also needs more code – load and save are good, but the web application also requires a getList method, and generally for the DAO to plug into the OrderDAO interface that’s used throughout the rest of the code base.

Lab workspace: Labs/Lab6

Backup of starter code: Examples/Wholesale/Web/Step10

Answer folder(s): Examples/Wholesale/Web/Step11

Files: docroot/WEB-INF/Wholesale-servlet.xml src/cc/sales/db/OrderDAOImplJDBC.java

Instructions:

1. To change DAO implementations, open Wholesale-servlet.xml and remove the declaration of the “database” bean. Replace it with a call to import the definitions already in place for the standalone application:

<import resource="Database.xml" />

By the way, if the DAO class were already complete – there’s your reconfiguration. The whole application shifts from text files to relational data right there.

2. Ah, but the DAO class is not complete! If you run ant now to build the web application, you’ll see that Tomcat has trouble instantiating all the beans, because several beans are wired to the “database” bean but they expect an OrderDAO implementation. OrderDAOImplJDBC shares two methods with this interface, but it’s not a complete implementation yet.

3. Open the source file, OrderDAOImplJDBC.java, and start off by making the class implement the OrderDAO interface.

4. To implement the missing method getList, you’ll need a new RowMapper, since you need to adapt a query that will return a single column of strings to a List of strings. Use OrderMapper as a template and create an inner static class StringMapper.

5. Create a private static final field stringMapper and set it to an instance of your new StringMapper class.

6. Now implement getList: start by calling template.query on the SQL query, “select distinct feed from ordr”, also passing stringMapper.

LAB 6

Page 239: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Chapter 6

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

229

Integrating the Wholesale Database LAB 6

7. A little adaptation is called for here: the interface calls for a string array, not a list. Java-5 parameterized collection types will make this fairly easy, but you do have to allocate the array and let the list populate it. Create an array of strings called results and allocate the right number of string references based on the size of the list you got back from template.query.

8. Now call toArray on your list, passing the results array. You can return the results of this call directly, as the result of getList.

9. Build the application and see that it deploys cleanly to Tomcat. You can test it now: see that everywhere feeds are used, the feed names are now just “Apples”, “Furniture”, etc. – no .txt suffix. The rest of the starter data is the same. Make some changes by way of buildFeed.jsp and see that they persist in later loads of feeds.jsp and process.jsp. You can also use ij to check the database contents.

Page 240: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,
Page 241: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

APPENDIX A

LEARNING RESOURCES

Page 242: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Appendix A

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

232

Page 243: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Appendix A

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

233

Books Johnson, Hoeller, Expert One-on-One J2EE Development without EJB, Wrox.

A bit of an ad for Spring, but it does develop the thesis of lightweight container and a beans-based framework vs. the weight of EJB.

Johnson, Hoeller, et. al., Professional Java Development with the Spring Framework, Wrox.

This is more overtly a developer’s guide for Spring. Walls, Spring in Action, Manning. Harrop, Machacek, Pro Spring, A-press.

Rob Harrop is another senior member of the Spring team. Gamma, Helm, Vlissides, Johnson, Design Patterns: Elements of Reusable Software, Addison-Wesley.

The essential text on design patterns, well worth the read for its own sake but also useful for understanding more of why Spring is laid out the way it is, and works the way it works: factory, decorator, template method, strategy, etc.

Alur, Crupi, Malks, Core J2EE Design Patterns, Sun Microsystems Press.

The best-known work on J2EE patterns, again informative with an eye towards Spring: front controller, intercepting filter, DAO, etc.

Bauer, King, Hibernate in Action, Manning. Elliott, Hibernate: A Developer’s Notebook, O’Reilly.

Page 244: The Spring Framework · Java EE: The Good, The Bad, and the Ugly • Java EE establishes a division of labor between containers and components; this is different for web components,

The Spring Framework Appendix A

© 2006-2007 Will Provost. All rights reserved by Capstone Courseware, LLC.

234

Specifications and Technical Documentation The Spring Framework home page: http://www.springframework.org

Bookmark – reference manual: http://static.springframework.org/spring/docs/2.0.x/reference/index.html

Bookmark – developer forum: http://forum.springframework.org

Web Resources Article on extensible XML authoring for the Spring IoC container:

http://www.springframework.org/docs/reference/new-in-2.html Spring Web (was a.k.a. Spring MVC) tutorial:

http://www.springframework.org/docs/MVC-step-by-step /Spring-MVC-step-by-step-Part-3.html

Good tutorial on Spring JDBC DAOs – Spring 1.2 but all valid for 2.0:

http://www.laliluna.de/eclipse-spring-jdbc-tutorial-en.html Some insights on combining Spring and Hibernate

http://www.shoesobjects.com/blog/2004/11/21/1101083542880.html The Spring IDE project

http://www.springide.org/project