Photo by annia316 - http://www.flickr.com/photos/annia316/754581568/
del.icio.us Digg DZone Reddit StumbleUpon
Software Development

Annotation-Based MVC in Spring 2.5

Simplify Spring 2.5 MVC configuration with Java annotations.

Spring 2.5 introduces annotation-based configuration for MVC controllers. In this short article I'll describe at a high level what you need to do to migrate your Spring 2.0 app over to Spring 2.5, at least as far as MVC is concerned. For information on migrating the other tiers, please see my article Annotation-Based Autowiring in Spring 2.5.

First make sure you drop spring-webmvc.jar onto your classpath. The DispatcherServlet is no longer part of spring.jar; it's in a separate module now.

Any given controller class can be set up in one of two ways. (And you can use both approaches in a single app.) Either the controller can handle a single action or else it can handle multiple actions. Usually a form "action", which really includes initially serving up the form and then accepting submissions of that form, would be handled with the first sort of controller, and non-form actions can be combined into a single controller, with actions being represented by methods.

Here's an extremely basic multi-action controller that handles three separate actions (mapped to methods). The actions don't do anything at all other than serve up the requested page.

package demo;
    
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
    
@Controller
public class SimpleController {
    
    @RequestMapping("/index.html")
    public void indexHandler() {
    }
    
    @RequestMapping("/about.html")
    public void aboutHandler() {
    }
    
    @RequestMapping("/admin.html")
    public void adminHandler() {
    }
}

Even though this is just about the simplest possible controller, there are still a few important points to highlight, especially if you're coming from earlier versions of Spring. First you will note that the controller is a POJO. It does not extend AbstractController or any of the other controller classes that you would have extended with Spring 2.0 or earlier. Second, notice the annotations. I've marked the controller itself with a @Controller annotation and the individual methods with @RequestMapping annotations. (I mentioned above that you can also map a controller to a single action; in that case you would attach the @RequestMapping annotation to the controller class itself. I'm not doing that here though.) Note also that I'm doing the URL mapping with the annotation. Pretty cool to have this option. Finally, though you can't tell from the controller, I'm using the request URL to specify the logical view name. Unless you specify otherwise, the DispatcherServlet will automatically assume that /index.html maps to the logical name "index", that /admin.html maps to the logical name "admin", etc. (Internally, it creates an instance of DefaultRequestToViewNameTranslator, though you don't see this unless you want to.) This is an example of Spring's movement toward the convention-over-configuration philosophy.

Now you need to make sure your application context config file is set up. Here's what I have:

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
    <context:component-scan base-package="demo"/>
    
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

The <component-scan> thing runs through your classes to find controllers and their annotation-based configuration. It knows which classes are controllers, as you may have guessed, because you used the @Controller annotation to label the controllers. Spring also supports @Repository for DAO layers, @Service for service layers, and @Component as a general stereotype over @Controller, @Repository and @Service.) The view resolver is just like it was with Spring 2.0.

Those are the basics. Of course there's a lot more you're going to want to do; for example, you'll want to pass in request parameters, process requests, return model objects, etc. But hopefully you'll find it useful to have a minimalistic example that gets you off the ground. Good luck!

Social bookmarks: del.icio.us Digg DZone Reddit StumbleUpon

Comments (3)

For your model, the M in your MVC you may consider using SQLOrm along with Spring JDBC.
See
http://sqlorm.sourceforge.net/
By Kasper Graversen on Feb 26, 2008 at 1:34 PM PST
in case of viewResolver, here we assume that we dump all the jsp files inside /WEB-INF/jsp.
what if we have different folder inside jsp folder. how do we access those files.

I tried doing.
@RequestMapping("admin/admin.html")
public void adminHandler() {
}
but it didn't work. (i am just trying to show the page by directly typing the URL).

Thanks
By puran on Mar 18, 2008 at 11:45 AM PDT
Hi Puran. Try using

@RequestMapping("/admin/admin.html")

Note the leading slash. Let me know if that doesn't work.
By Willie Wheeler on Mar 18, 2008 at 10:28 PM PDT
Post a comment
Home | Consulting | Articles | Blog | About | Contact
Copyright © 2008 Wheeler Software, LLC.