MemeStorm

Exploring the Spring Framework and Application Development

Spring Binding and Validation: Introduction

Posted in All by Jon on the February 20th, 2006

You want to slurp in some data, perhaps from a simple form or from
request parameters. To do this, we’ll explore the AbstractCommandController and learn about the related issues of binding and validation. Spring makes this kind of thing pretty effortless, and this will serve as the foundation of exploring more advanced form-handling.

How to do it

The controllers we wrote about in previous blog entries, such as the MultiActionController, are generally used for carrying out actions. What if you wanted to rather input some data first, perhaps through request parameters? Well one way to do this is the hard way:

String val = (String) request.getParameter("someParamName");

Those were the days. Untyped, inflexible, error-prone, with all sorts of casting (imagine if I wanted a date or an integer).

A much better approach use data binding - let Spring bind the incoming data to a Plain Old JavaBean (POJO) for you - then you can simply use that POJO as you’d expect. Spring calls these beans commands, which I think is a bit of a misnomer, but there you go. Let’s see this in action. First, we’re going to modify our dispatch-servlet.xml configuration file to include a new controller:

<bean id="commandController"
  class="com.memestorm.web.CommandController">
</bean>

Now let’s modify our handler mappings (see previous blog entries if you need to understand these) to include a mapping to our command controller:

/cmd=commandController
/*=dispatchController

So in theory now, something like http://localhost:8080/send/cmd?age=10 will get sent to our command controller. Now the command controller we’ll use is the simplest around. It extends the AbstractCommandController. Here’s the code:

public class CommandController extends AbstractCommandController {

  public CommandController() {
    setCommandClass(SimpleCommand.class);
  }

  protected ModelAndView handle(HttpServletRequest request,
		HttpServletResponse response, Object command,
                BindException errors) throws Exception {

    SimpleCommand cmd = (SimpleCommand) command;

    PrintWriter pw = response.getWriter();
    pw.println(cmd);
    return null;
  }
}

The first thing you’ll notice (probably because I have it in bold) is that the constructor calls setCommandClass() with the class that will hold the incoming values. This is the command class I spoke about earlier. All incoming parameters are mapped onto this class, automatically, for you. We pass the setCommandClass() the class so that it can instantiate a new instance every time the controller is invoked. Now take a look at the handle() method, somewhat more complicated than the others that we’ve seen in Basic Spring Web MVC Example. The two extra parameters are the command (which Spring will have created and populated for you), and an object listing errors (which we’ll describe later).

The method is pretty simple: It casts the command object to the expected type, and then writes it to the response. Let’s look at the command object:

public class SimpleCommand {
 Integer age;
 String name;

 public String getName() {return name;}

 public void setName(String name) {this.name = name;}

 public Integer getAge() {return age;}

 public void setAge(Integer age) {this.age = age;}

 public String toString() {
   return "Name=[" + this.name + "], Age=[" + this.age + "]";
 }
}

You must admit, that’s pretty straightforward. A typed container, just ready to be populated by incoming values. Now, if you invoke something like http://localhost:8080/skeleton3/send/cmd?name=Jon&age=30 you’ll see the output as Name=[Jon], Age=[30]. This is pretty darn nice for a number of reasons:

  • Notice that I didn’t write any code to bind the incoming parameters to the command bean. It’s automatic.
  • Notice that the command bean is typed - getAge() returns an Integer and somehow Spring converted the incoming field to the appropriate type automatically.

This is a considerable step up from getRequestParameter(). It even works for a form input. For example, here is a simple form that you can use to invoke our controller:

<form action="send/cmd" method="post">
 Name: <input type="text" name="name" />
 Age: <input type="text" name="age" />
</form>

But wait, there’s more! If we extend our handler() method to dump some information found in the errors parameter, we’ll see further magic:

pw.println("<hr>" + "Error count=" + errors.getErrorCount());
pw.println("<br>Errors for age field"  + errors.getFieldErrors("age"));
pw.println("<br>Input value for age field: " + errors.getFieldValue("age"));
pw.println("<br>" + errors.getGlobalErrors());

Now if we invoke it with an error in the age value (for example, some letters instead of digits) as in: http://localhost:8080/skeleton3/send/cmd?name=Jon&age=crikey we’ll see the following output:

Name=[Jon], Age=[null]
<hr>Error count=1
<br>Errors for age field[Field error in object 'command' on field 'age': rejected value [crikey]; codes [typeMismatch.command.age,typeMismatch.age,typeMismatch.java.lang.Integer,typeMismatch]; arguments [MessageSourceResolvable: codes [command.age,age]; arguments []; default message [age]]; default message [Failed to convert property value of type [java.lang.String] to required type [java.lang.Integer] for property 'age'; nested exception is java.lang.NumberFormatException: For input string: "crikey"]]
<br>Input value for age field: crikey

Now notice that the age value is null (it can’t convert ‘crikey’), notice that we have an error count, that we have access to the original text that the user entered, and we have a good error message too. That’s a lot of magic for very little effort.

But wait, there’s even more. With a simple change to the constructor, we can validate input values too. Here is an example modification:

public CommandController() {
  setCommandClass(SimpleCommand.class);
  setValidator(new Validator(){
    public boolean supports(Class clazz) {
      return (clazz.equals(SimpleCommand.class));
    }
    public void validate(Object command, Errors errors) {
      SimpleCommand incoming = (SimpleCommand) command;
      ValidationUtils.rejectIfEmpty(errors, “age”, “required.age”);
      if (incoming.getAge() != null && incoming.getAge() > 30)
        errors.reject(”over.the.hill”, “too old”);
   }});
}

As you can see, we’ve set a validator. A validator simply implements the Validator interface—here we’ve done it with a simple anonymous class. You can instead write full classes for the validators and wire them in with the web context instead - in that way you can promote some reuse with your validators too. The validator interface has two methods. supports() tells the system what kind of class it validates. The validate method performs the actual validation. We make use of ValidationUtils to ensure that the age is not empty. You can, instead, write your own validation as we do checking that the age is not too high. So now, if we pass in an age of 34 say, we’ll get the following output:

...
[Error in object 'command': codes [over.the.hill.command,over.the.hill]; arguments []; default message [too old]]

There is in fact a little more magic too (message interpretation) but that will have to wait for another day.


Print This Post Print This Post

Loading resources from files or the classpath

Posted in All by Jon on the February 19th, 2006

You want to load resources from the file system or classpath from
within beans initialized by a Spring context.

Background

Our HSQLDB utility class needs to load the SQL to create the database every time our application starts, as outlined in a Embedded Database Starting Up With Web Context. How does this bean get access to the file? Well, in the context configuration we supplied a file location, for example:

<bean id="databaseUtils" class="com.memestorm.utils.db.HSQLDB">
  <property name="location“>
    <value>/db/init.sql</value>
  </property>
</bean>

So, how can we actually get to the file?

How to do it

The easiest way is to have your bean implement the ResourceLoaderAware interface. This will then ensure that the setResourceLoader(ResourceLoader resourceLoader) method will get called on your bean, with a magic resource loader. (Look here for more information on the aware interfaces.)

The ResourceLoader
class is a fantastic utility class provided by Spring, that allows you
to load resources from all sorts of locations. Given the location above, the resource loader will look for the file db/init.sql relative to the root of the web application (when used from a web context). Our bean simply uses the location as follows:

Resource sql = this.resourceLoader.getResource(this.location);
JdbcTemplate jt = new JdbcTemplate(this.dataSource);
jt.execute(IOUtils.toString(sql.getInputStream()));

It’s so simply it belies how easy this makes life! To load from an arbitrary file location, use the file: prefix instead. For example, file:///temp/foobar.sql. You can also try and locate something in the classpath using the classpath prefix. For example, classpath:config.xml.

Have fun.


Print This Post Print This Post

Use Spring’s bean lifecycle callback methods to control your destiny

Posted in All by Jon on the February 19th, 2006

You want to run an initialize or destroy method on a bean after the context creates it. These lifecycle methods allow you to grab and release resources.

How to do it

Well, we did this in the previous blog entry, making use of an ApplicationListener and InitializingBean. This was overkill! There’s a better way that doesn’t require these interfaces. To have a method execute after the bean is initialized, or just before it’s destroyed (ie. at context start up or shutdown), simply modify your configuration file as follows:

<bean id="databaseUtils" class="com.memestorm.utils.db.HSQLDB"
  init-method=”initialize” destroy-method=”destroy”>
</bean>

You can of course omit either one, or both, of these attributes. The values of the attributes indicate the method that should be invoked. So for example, given the above definition the initialize() and destroy() method of the HSQLDB object will be invoked. This is great, and avoids any dependence on Spring interfaces.

If you’d like the same functionality relying on interfaces instead, then simply have the class implement InitializingBean and DisposableBean instead. In this case the configuration file will not have a init-method or destory-method attribute.


Print This Post Print This Post

Embedded Database Starting Up With Web Context

Posted in All by Jon on the February 17th, 2006

We want to introduce a database into our sample application, in an
unobtrusive way requiring little in the way of configuration. We’ll do this with an all-Java in-memory database, and along the way learn a little about Aware interfaces, and running methods on context startup or shutdown. The result is a deployed WAR that has an in-built database.

Background

I was thinking about how to introduce databases without requiring you lot to do a lot of downloads, installation and configuration. Then it came to me - an in-memory database would be great. The full Spring distribution comes with HSQLDB, which is what we’ve used below. We’ve also got this working with Apache Derby.

Because we’ve opted for in-memory, and non-persistence, we have to essentially create the database and the tables every time we start up our application. This takes no time at all, but does force us to look a little at how a configuration context starts up and shuts down.

How to do it: Configuration

We’ll walk through the configuration by looking at the changes made to skeleton1, introduced in Basic Spring Web MVC Example.

First, let’s look at changes to our build.xml. The only thing you’ll notice is the addition of several libraries:

<include name="hsqldb.jar" />
<include name="commons-dbcp.jar" />
<include name="commons-pool.jar" />
<include name="commons-io.jar" />

The first is the database engine itself, the next two are for interfacing to the database, and the last is simply a utility library that we use later.

Now the way you typically integrate a database with a Spring application, is to introduce a data source bean. Data sources are the bridge between your application and the database. Even though you may use different database implementations, the data source will hide the details. Here’s our implementation:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource“>
<property name=”driverClassName”>
<value>${jdbc.driverClassName}</value>
</property>
<property name=”url”>
<value>${jdbc.url}</value>
</property>
</bean>

You’ll note we’ve externalized (see Parameterizing Spring’s Configuration Files, and BeanFactoryPostProcessors) the name of the database driver and URL used for connecting to the database. You’ll find them in jdbc.properties:

jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:mem:exampledb

The bean dataSource is an instance of BasicDataSource supplied by the DBCP library, which in turn implements the necessary interface, javax.sql.DataSource. Any interface with a database generally needs a bean that implements this interface. The DBCP version, which we’ve used, creates a data source by wrapping the necessary functionality around a database driver, which you can see we’ve supplied as a parameter. DBCP can add additional functionality such as connection pooling, which we’ll see in a later story.

This is pretty much standard - the details of what kind of data source to create, and which database driver to use, will vary - but the intent will remain no matter what db you connect to.

The database we’re using has a special driver class - normally a driver class allows you to connect to a running database. This driver class allows the same, but it also starts the database! So this database runs in the same VM as your code.

How to do it: Using the database

At this point (ignoring creating tables), we’re ready to use our database. Typically you would do this by making sure some data access objects have access to the data source. We’re not there yet. Instead, we’re going to make sure our controller has access to the data source. In that way we can add another handler method, which will in turn query the database:

<bean id="dispatchController"
class="com.memestorm.web.DispatchController">
<property name="dataSource"><ref bean="dataSource“/></property>
</bean>

As you can see, we simply pass in the data source bean defined above. We’ve added an additional method to our dispatch controller too:

public ModelAndView listFromDB(HttpServletRequest request,
HttpServletResponse response) throws Exception {
JdbcTemplate jt;
jt = new JdbcTemplate(this.dataSource);
jt.update(”insert into myTable values (’jon’,31)”);
List rows = jt.queryForList(”select * from myTable”);
ModelAndView mav = new ModelAndView(”listview”);
mav.addObject(”rows”, rows);
return mav;
}

Spring provides a really nice templating approach to interfacing with a database, which we’ll describe in a later story. You should be able to figure it out though. You use the data source to construct a JdbcTemplate object, and then use this to execute SQL. In this case, we execute an SQL update - inserting a row into the database. We then perform a query (an SQL select), and pass the results to our view (listview). What does the view look like?

<body>
Here are the results from the database:<br />
<%= request.getAttribute("rows") %>
</body>

It simply prints out the result! So, if we invoke our handler method:

http://localhost:8080/skeleton2/send/listFromDB

twice, then we’ll see this as output:

Here are the results from the database:
[{NAME=jon,AGE=31},{NAME=jon,AGE=31}]

Neat.

How to do it: Setting up the database

As mentioned, we start up with a clean database every time the web application is deployed. We also want to shut the database down nicely when we shut the application down. You’ll be astounded how easy this is. We’ll simply define one more bean:

<!--  can be used to initialize and shutdown the database instance -->
<bean id="databaseUtils" class="com.memestorm.utils.db.HSQLDB">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="location">
<value>${db.sql.init}</value>
</property>
</bean>

That’s it! That’s pretty unobtrusive. The magic happens in HSQLDB (note how we pass it the data source, and a file location). Let’s explore this class:

public class HSQLDB  implements ApplicationListener … {
…
}

The first thing to note is that it implements ApplicationListener. Any bean that you register in the configuration context which implements this interface will automatically get sent important lifecycle events. All you have to do is then implement an onApplicationEvent() method. Here is our implementation:

public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextClosedEvent) {
shutdownDB();
}
}

We wait for a particular event, and when we get it, invoke shutdown. Simple! So in contrast, how do we do something when the context starts up? Well, we implement another interface:

public class HSQLDB  implements InitializingBean, ApplicationListener … {
…
}

What happens then is that when the context is initialized, and all properties are set, the context will invoke the afterPropertiesSet() method on all beans that implement the interface. How simple is that? Here is what we do:

public void afterPropertiesSet() throws Exception {
Resource sql = new ServletContextResource(this.servletContext, getLocation());
JdbcTemplate jt = new JdbcTemplate(this.dataSource);
jt.execute(IOUtils.toString(sql.getInputStream()));
}

As you can see, we simply grab the file given by the location variable, grab its contents, and execute it as SQL. Our file contains the following:

create table myTable (name varchar(40), age int);

You’ll notice that to grab the file at the location (which is relative to the root of the web application), we actually need the servlet context. So how can any bean get access to the servlet context in which it is running? Well, again, you just implement an interface!

public class HSQLDB  implements InitializingBean, ApplicationListener
ServletContextAware {
…
}

If you do this, Spring will again automatically invoke the setServletContext(ServletContext servletContext) on your bean, passing you the context which you can store. Neat hey? That’s it!

Recap

We’ve covered quite a bit here, so let’s recap:

  • Implementing ServletContextAware, one of the “Aware” interfaces, will result in the context telling your bean what the servlet context is. This is a service provided by any web application context
  • Implementing ApplicationListener allows you to listen to context life cycle events. Another interesting event is ContextRefreshedEvent and RequestHandledEvent
  • Implementing InitializingBean allows our beans to do somem work after all their properties have been set by the Bean Factory.

Additional Material

Our sample does just a little more than this. Instead of mixing in our database configuration with our dispatch configuration (dispatch-servlet.xml), we’ve put them in a separate file, jdbcContext.xml. To load this, we’ve introduced a new configuration to our dispatcher servlet (in web.xml):

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml  /WEB-INF/jdbcContext.xml
</param-value>
</context-param>

This does what it says on the tin - it loads a number of configurations from a “space separated” list of files. In this way you can keep a number of configuration files, keeping them all neat and tidy.

Download

It’s been a long journey, but hopefully a rewarding one. You’re probably keen to download the code and build your own WAR. Here it is:

skeleton2.zip


Print This Post Print This Post Next Page »