Spring
Spring
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
SUBSCRIBE
Blogs
SPRINGSOURCE BLOG
GREEN BEANS: GETTING STARTED WITH SPRING MVC
Posted on January 4th, 2011 by Colin Sampaleanu in 3.0, Green Beans, Spring, Web.
SEARCH
Spring MVC, a part of the core Spring Framework, is a mature and capable action-response style web framework, with a wide range of capabilities and options aimed at handling a variety of UI-focused and non-UI-focused web tier use cases. All this can potentially be overwhelming to the Spring MVC neophyte. I think it's useful for this audience to show just how little work there is to get a bare Spring MVC application up and running (i.e. consider my example something akin to the world's simplest Spring MVC application), and that's what I'll spend the rest of this article demonstrating. I'm assuming you are familiar with Java, Spring (basic dependency injection concepts), and the basic Servlet programming model, but do not know Spring MVC. After reading this blog entry, readers may continue learning about Spring MVC by looking at Keith Donald's Spring MVC 3 Showcase, or the variety of other online and print resources available that cover Spring and Spring MVC. RICH WEB APPLICATIONS SPRING Bangalore, 5 Nov 2013
Learn More
WITH
A note on dependencies and build systems: this article does not assume that you are using a particular build system, e.g. Maven, Gradle or Ant. A fairly minimal sample Maven POM file is AUTHORS includes as an example at the end of the article. Spring MVC includes most of the same basic concepts as other so-called web MVC frameworks. Incoming requests enter the framework via a Front Controller. In the case of Spring MVC, this is an actual Java Servlet called D i s p a t c h e r S e r v l e t . Think of D i s p a t c h e r S e r v l e t as the gatekeeper. It doesn't perform any real web or business logic, but rather delegates to POJOs called Controllers where the real work is done (either in whole or via the back-end). When the work has been done, it's the responsibility of Views to produce the output in the proper format (whether that's a JSP page, Velocity template, or JSON response). Strategies are used to decide which Controller (and which method(s) inside that Controller) handles the request, and which View renders the response. The Spring container is used to wire together all these pieces. It all looks something like this:
Adam FitzGerald Alan Stewart Andrew Eisenberg Andy Wilkinson Ben Alex Ben Hale Chris Frost Christian Dupuis Craig Walls David Turanski Glyn Normington Guillaume Laforge Helena Edelson Jennifer Hickey John Hann Jon Travis Juergen Hoeller Kris De Volder Mark Fisher Mark Thomas Michael Isvy Oleg Zhurakousky Paul Chapman Peter Ledbrook Rob Harrop Rod Johnson Roy Clarkson Stefan Schmidt Adrian Colyer Alexis Richardson Andy Clement Arjen Poutsma Ben Corrie Chris Beams Chris Richardson Costin Leau Dave Syer Gary Russell Graeme Rocher Gunnar Hillert James Tyrrell Jeremy Grelle Jon Brisbin Josh Long Keith Donald Luke Taylor Mark Pollack Martin Lippert Mike Wiesner Oliver Gierke Peter Cooper-Ellis Ramnivas Laddad Rob Winch Rossen Stoyanchev Scott Andrews Thomas Risberg
CATEGORIES
2.0 (29) 3.0 (38) AMQP (7) AOP (20) Big Data (4) Builds (16) Business (28) 2.5/2.1 (18) 3.1 (18) Android (4) Apache Tomcat (7) Books (3) Bundlor (1) Cloud Computing (51)
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
1/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
Cloud Foundry (18) Data Access (42) Enterprise Integration (26) Green Beans (6) Hadoop (2) Hyperic IQ (1) Java (84) JMX (4) Management Tools (1) OSGi (72) Scala (2) Slices (1) Spring Batch (2) Spring Events (23) Spring Python (4) tc Server (10) Tools (53) VMware (7) Web Flow (9) Containers (12) dm Server (64) Google (3) Groovy/Grails (54) Hyperic HQ (6) IOC Container (32) JMS (6) JSF (2) Open Source (90) Roo (17) Security (23) Spring (390) Spring Data (15) Spring Integration (19) SpringSource (54) Testing (14) Training/Certification (2) Web (51) Web Services (7)
WEBSITES
Spring Framework Spring Training
ARCHIVES
August 2013 June 2013 April 2013 February 2013 December 2012 October 2012 August 2012 June 2012 April 2012 February 2012 December 2011 October 2011 August 2011 June 2011 April 2011 February 2011 December 2010 October 2010 August 2010 June 2010 April 2010 February 2010 December 2009 October 2009 August 2009 June 2009 April 2009 February 2009 December 2008 October 2008 August 2008 June 2008 April 2008 February 2008 December 2007 October 2007 August 2007 June 2007 April 2007 February 2007 December 2006 October 2006 August 2006 May 2006 March 2006 July 2013 May 2013 March 2013 January 2013 November 2012 September 2012 July 2012 May 2012 March 2012 January 2012 November 2011 September 2011 July 2011 May 2011 March 2011 January 2011 November 2010 September 2010 July 2010 May 2010 March 2010 January 2010 November 2009 September 2009 July 2009 May 2009 March 2009 January 2009 November 2008 September 2008 July 2008 May 2008 March 2008 January 2008 November 2007 September 2007 July 2007 May 2007 March 2007 January 2007 November 2006 September 2006 July 2006 April 2006 February 2006
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
2/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
August 2004
W E B I N F / w e b . x m l
< ? x m lv e r s i o n = " 1 . 0 "e n c o d i n g = " U T F 8 " ? > < w e b a p pv e r s i o n = " 2 . 5 "x m l n s = " h t t p : / / j a v a . s u n . c o m / x m l / n s / j a v a e e " x m l n s : x s i = " h t t p : / / w w w . w 3 . o r g / 2 0 0 1 / X M L S c h e m a i n s t a n c e " x s i : s c h e m a L o c a t i o n = " h t t p : / / j a v a . s u n . c o m / x m l / n s / j a v a e eh t t p : / / j a v a . s u n . c o m / x m l / n s / j a v a e e / w e b a p p _ 2 _ 5 . x s d " >
< ! -P r o c e s s e sa p p l i c a t i o nr e q u e s t s> < s e r v l e t > < s e r v l e t n a m e > a p p S e r v l e t < / s e r v l e t n a m e > < s e r v l e t c l a s s > o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t < / s e r v l e t c l a s s > < i n i t p a r a m > < p a r a m n a m e > c o n t e x t C o n f i g L o c a t i o n < / p a r a m n a m e > < p a r a m v a l u e > / W E B I N F / s p r i n g / a p p S e r v l e t / s e r v l e t c o n t e x t . x m l < / p a r a m v a l u e > < / i n i t p a r a m > < l o a d o n s t a r t u p > 1 < / l o a d o n s t a r t u p > < / s e r v l e t >
< s e r v l e t m a p p i n g > < s e r v l e t n a m e > a p p S e r v l e t < / s e r v l e t n a m e > < u r l p a t t e r n > / < / u r l p a t t e r n > < / s e r v l e t m a p p i n g > < / w e b a p p >
A number of things are being done here: We register the DispatcherServlet as as a Servlet called
a p p S e r v l e t
3/12
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
We map this Servlet to handle incoming requests (relative to the app path) starting with "/" We use the C o n t e x t C o n f i g L o c a t i o ninit parameter to customize the location for the base configuration XML file for the Spring Application Context that is loaded by the DispatcherServlet, instead of relying on the default location of <servletname>-context.xml). Wait, What if Somebody Doesn't Want to Configure Spring via XML? The default type of Application Context loaded by the DispatcheServlet expects to load at least on XML file with Spring bean definitions. As you'll see, we'll also enable Spring to load Java-based config, alongside the XML. Everybody will have their own (sometimes very strong) opinion in this area, but while I generally prefer-Java based configuration, I do believe that smaller amounts of XML config for certain areas can sometimes still make more sense, for one of a number of reasons (e.g. ability to change config without recompilation, conciseness of XML namespaces, toolability, etc.). On this basis, this app will use the hybrid approach, supporting both Java and XML. Rest assured that if you prefer a pure-Java approach, with no Spring XML at all, it's pretty trivial to achieve, by setting one init param in w e b . x m lto override the default Application Context type and use a variant called A n n o t a t i o n C o n f i g W e b A p p l i c a t i o n C o n t e x t instead.
The Controller
Now let's create a minimal controller:
p a c k a g ex y z . s a m p l e . b a r e m v c ;
i m p o r to r g . s p r i n g f r a m e w o r k . s t e r e o t y p e . C o n t r o l l e r ; i m p o r to r g . s p r i n g f r a m e w o r k . w e b . b i n d . a n n o t a t i o n . R e q u e s t M a p p i n g ;
/ * * *H a n d l e sr e q u e s t sf o rt h ea p p l i c a t i o nh o m ep a g e . * / @ C o n t r o l l e r p u b l i cc l a s sH o m e C o n t r o l l e r{
Let's walk through the key aspects of this class: The class has been annotated with the @ C o n t r o l l e rannotation, indicating that this is a Spring MVC Controller capable of handling web requests. Because @ C o n t r o l l e ris a specialization of Spring's @ C o m p o n e n tStereotype annotation, the class will automatically be detected by the Spring container as part of the container's component scanning process, creating a bean definition and allowing instances to be dependency injected like any other Spring-managed component. The h o m emethod has been annotated with a @ R e q u e s t M a p p i n gannotation, specifying that this method should handle web requests to the path "/", i.e. the home path for the application. The h o m emethod simply logs a message to system out, and then returns W E B I N F / v i e w s / h o m e . j s p , indicating the view which should handle the response, in this case a JSP page. (If hardcoding the entire view path including WEB-INF prefix, and the fact that it's a JSP, seems wrong to you, you are right. We'll deal with this later) Now, we need to create the view. This JSP page will simply print a greeting.
W E B I N F / v i e w s / h o m e . j s p
< % @t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / c o r e "p r e f i x = " c "% > < % @p a g es e s s i o n = " f a l s e "% > < h t m l > < h e a d > < t i t l e > H o m e < / t i t l e > < / h e a d > < b o d y > < h 1 > H e l l ow o r l d ! < / h 1 > < / b o d y > < / h t m l >
Finally, as previously mentioned, we need to create a minimal Spring Application Context definition file.
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
4/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
W E B I N F / s p r i n g / a p p S e r v l e t / s e r v l e t c o n t e x t . x m l
< ? x m lv e r s i o n = " 1 . 0 "e n c o d i n g = " U T F 8 " ? > < b e a n sx m l n s = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / b e a n s " x m l n s : x s i = " h t t p : / / w w w . w 3 . o r g / 2 0 0 1 / X M L S c h e m a i n s t a n c e " x m l n s : m v c = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / m v c " x m l n s : c o n t e x t = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / c o n t e x t " x s i : s c h e m a L o c a t i o n = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / m v ch t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / m v c / s p r i n g m v c 3 . 0 . x s d h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / b e a n sh t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / b e a n s / s p r i n g b e a n s 3 . 0 . x s d h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / c o n t e x th t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / c o n t e x t / s p r i n g c o n t e x t 3 . 0 . x s d " >
< / b e a n s >
Let's examine the contents of this file: You'll note that a few different Spring XML namespaces are being used: context, mvc, and the default beans The <context:component-scan> declaration ensures the Spring container does component scanning, so that any code annotated with @ C o m p o n e n t subtypes such as @ C o n t r o l l e r is automatically discovered. You'll note that for efficiency, we limit (to x y z . s a m p l e . b a r e m v cin this case) what part of the package space Spring should scan in the classpath The <mvc:annotation-driven> declaration sets up Spring MVC's support for routing requests to @Controllers, as well as how some things like conversion, formatting and validation are handled (with some sensible defaults based on what (libraries) is present in your classpath, and the ability to override if needed) The web app is now ready to run. Assuming the Servlet container (tc Server in my case) is set to listen on localhost:8080, starting the application and then hitting the URL h t t p : / / l o c a l h o s t : 8 0 8 0 / b a r e m v cvia our browser results in a display of the expected greeting:
As trivial as it is, running this application involves all the major pieces of a working Spring MVC application. Let's walk through the major sequences and component interactions: When the web app starts up, the DispatcherServlet is loaded and initialized because of the entry in w e b . x m l . The DispatcherServlet loads an annotation-based Application Context, which has been configured to scan for annotated components via a regular expression specifying the base package(s). Annotated components such as the HomeController are detected by the container. The HTTP request to h t t p : / / l o c a l h o s t : 8 0 8 0 / b a r e m v chits the servlet engine and is routed to our (baremvc) webapp. The implicit "/" path at the end of the URL matches the regex that has been registered for the DispatcherServlet, and the request is routed to it The DispatcherServlet needs to decide what to do with the request. It uses a strategy called a H a n d l e r A d a p t e rto decide where to route
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
5/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
the request. The specific HandlerAdapter type (or types, since they can be chained) to be used can be customized, but by default, an annotation-based strategy is used, which routes requests appropriately to specific methods in classes annotated as @ C o n t r o l l e r , based on matching criteria in @ R e q u e s t M a p p i n gannotations found in those classes. In this case, the regex on the home method is matched, and it's called to handle the request. The home method does its work, in this case just printing something to system out. It then returns a string that's a hint (in this case, a very explicit one, W E B I N F / v i e w s / h o m e . j s p ) to help chose the View to render the response. The DispatcherServlet again relies on a strategy, called a V i e w R e s o l v e rto decide which View is responsible for rendering the response. This can be configured as needed for the application (in a simple or chained fashion), but by default, an I n t e r n a l R e s o u r c e V i e w R e s o l v e ris used. This is a very simple view resolver that produces a J s t l V i e wwhich simply delegates to the Servlet engine's internal R e q u e s t D i s p a t c h e rto render, and is thus suitable for use with JSP pages or HTML pages. The Servlet engine renders the response via the specified JSP
Spring MVC's V i e w R e s o l v e rStrategy is actually the mechanism meant to be used to achieve this looser coupling between the controller and the view. As already mentioned, in the absence of the application configuring a specific V i e w R e s o l v e r , Spring MVC sets up a default minimally configured I n t e r n a l R e s o u r c e V i e w R e s o l v e r , a very simple view resolver that produces a J s t l V i e w . There are potentially other view resolvers we could use, but to get a better level of decoupling, all we actually need to do is set up our own instance of I n t e r n a l R e s o u r c e V i e w R e s o l v e rwith slightly tweaked configuration. I n t e r n a l R e s o u r c e V i e w R e s o l v e remploys a very simple strategy; it simply takes the view name returned by the controller, and prepends it with an optional prefix (empty by default), and appends it with an optional suffix (empty by default), then feeds that resultant path to a J s t l V i e wit creates. The J s t l V i e wthen delegates to the Servlet engine's R e q u e s t D i s p a t c h e rto do the real work, i.e. rendering the template. Therefore, to allow the controller to return logical view names like h o m einstead of specific view template paths like W E B I N F / v i e w s / h o m e . j s p , we simply need to configure this view resolver with the prefix W E B I N F / v i e w sand the suffix . j s p , so that it prepends and appends these, respectively, to the logical name returned by the controller. One easy way to configure the view resolver instance is to introduce the use of Spring's Java-based container configuration, with the resolver as a bean definition:
p a c k a g ex y z . s a m p l e . b a r e m v c ;
i m p o r to r g . s p r i n g f r a m e w o r k . c o n t e x t . a n n o t a t i o n . B e a n ; i m p o r to r g . s p r i n g f r a m e w o r k . c o n t e x t . a n n o t a t i o n . C o n f i g u r a t i o n ; i m p o r to r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . V i e w R e s o l v e r ; i m p o r to r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . v i e w . I n t e r n a l R e s o u r c e V i e w R e s o l v e r ;
@ C o n f i g u r a t i o n p u b l i cc l a s sA p p C o n f i g{
/ /R e s o l v el o g i c a lv i e wn a m e st o. j s pr e s o u r c e si nt h e/ W E B I N F / v i e w sd i r e c t o r y @ B e a n V i e w R e s o l v e rv i e w R e s o l v e r ( ){ I n t e r n a l R e s o u r c e V i e w R e s o l v e rr e s o l v e r=n e wI n t e r n a l R e s o u r c e V i e w R e s o l v e r ( ) ;
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
6/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
r e s o l v e r . s e t P r e f i x ( " W E B I N F / v i e w s / " ) ; r e s o l v e r . s e t S u f f i x ( " . j s p " ) ; r e t u r nr e s o l v e r ; } }
We are already doing component scanning, therefore since @ C o f i g u r a t i o nis itself an @ C o m p o n e n t , this new configuration definition with the (resolver) bean inside it is automatically picked up by the Spring container. Then Spring MVC scans all beans and finds the resolver. This is a fine approach, but some people may instead prefer to configure the resolver as a bean in the XML definition file, e.g.
< ! -R e s o l v el o g i c a lv i e wn a m e st o. j s pr e s o u r c e si nt h e/ W E B I N F / v i e w sd i r e c t o r y> < b e a nc l a s s = " o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . v i e w . I n t e r n a l R e s o u r c e V i e w R e s o l v e r " > < p r o p e r t yn a m e = " p r e f i x "v a l u e = " / W E B I N F / v i e w s / "/ > < p r o p e r t yn a m e = " s u f f i x "v a l u e = " . j s p "/ > < / b e a n >
It's hard to make a case for this object that one particular approach is much better than the other, so it's really a matter of personal preference in this case (and we can actually see one of the strengths of Spring, its flexible nature).
i m p o r tj a v a . u t i l . C o m p a r a t o r ;
i m p o r to r g . s p r i n g f r a m e w o r k . b e a n s . f a c t o r y . a n n o t a t i o n . A u t o w i r e d ; i m p o r to r g . s p r i n g f r a m e w o r k . s t e r e o t y p e . C o n t r o l l e r ; i m p o r to r g . s p r i n g f r a m e w o r k . u i . M o d e l ; i m p o r to r g . s p r i n g f r a m e w o r k . w e b . b i n d . a n n o t a t i o n . R e q u e s t M a p p i n g ; i m p o r to r g . s p r i n g f r a m e w o r k . w e b . b i n d . a n n o t a t i o n . R e q u e s t M e t h o d ; i m p o r to r g . s p r i n g f r a m e w o r k . w e b . b i n d . a n n o t a t i o n . R e q u e s t P a r a m ;
/ * * *H a n d l e sr e q u e s t sf o rt h ea p p l i c a t i o nh o m ep a g e . * / @ C o n t r o l l e r p u b l i cc l a s sH o m e C o n t r o l l e r{
@ A u t o w i r e d C o m p a r a t o r < S t r i n g >c o m p a r a t o r ;
S t r i n go u t p u t=" A c c o r d i n gt oo u rC o m p a r a t o r ,' "+i n p u t 1+" 'i s"+i n E n g l i s h+" ' "+i n p u t 2+" ' " ;
m o d e l . a d d A t t r i b u t e ( " o u t p u t " ,o u t p u t ) ;
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
7/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
r e t u r n" c o m p a r e R e s u l t " ; } }
Key elements in the new code: We're using another @ R e q u e s t M a p p i n gannotation to make requests ending in with the path / c o m p a r eto the new compare method We are expecting the caller to pass us the two String input parameters as part of the GET request, so we grab them via the @ R e q u e s t P a r a mannotation. Note that we are relying on the default handling for this annotation, which assumes that these params are required. The client will receive an HTTP 400 error if they are missing. Note also that this is just one way of passing in parameters to a Spring MVC application. For example, it's easy to grab parameters that are embedded as part of the request URL path itself, for a more REST-style approach We use our Comparator instance to compare the two strings We stuff the comparison result into the Model object under the key r e s u l t , so that it can be accessed by the View. Think of a Model as a glorified hashmap, in simplest terms. While we could have modified our exisitng view to also be used to display the comparison results, we are instead using a new view template:
W E B I N F / v i e w s / c o m p a r e R e s u l t . j s p
< % @t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / c o r e "p r e f i x = " c "% > < % @p a g es e s s i o n = " f a l s e "% > < h t m l > < h e a d > < t i t l e > R e s u l t < / t i t l e > < / h e a d > < b o d y > < h 1 > < c : o u tv a l u e = " $ { o u t p u t } " > < / c : o u t > < / h 1 > < / b o d y > < / h t m l >
Finally, we need to supply the controller with a C o m p a r a t o rinstance to use. We have annotated the c o m p a r a t o rfield in the controller with Spring's @ A u t o w i r e dannotation (which will be detected automatically after the controler is detected) and instructs the Spring container to inject a C o m p a r a t o r into that field. Therefore, we need to ensure the container has one available. For this purpose, a minimal C o m p a r a t o rimplementation has been created, which simply does a case insensitive comparison. For simplicity's sake, this class has itself been annotated with Spring's @ S e r v i c eStereotype annotation, a type of @ C o m p o n e n tand thus will automatically be detected by the Spring container as part of the container's component scanning process, and injected into the controller.
p a c k a g ex y z . s a m p l e . b a r e m v c ;
i m p o r tj a v a . u t i l . C o m p a r a t o r ; i m p o r to r g . s p r i n g f r a m e w o r k . s t e r e o t y p e . S e r v i c e ;
Note that we could just as easily have declared an instance of this in the container via a Java based @ B e a ndefinition in an @ C o n f i g u r a t i o n class, or an XML based bean definition, and certainly those variants might be preferred in many cases for the greater level of control they offer. We can now start the application and access it with a URL such as
h t t p : / / l o c a l h o s t : 8 0 8 0 / b a r e m v c / c o m p a r e ? i n p u t 1 = D o n k e y & i n p u t 2 = d o g
to exercise the new code:
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
8/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
Next Steps
I've really only scratched the surface of what Spring MVC can do, but hopefully this blog post has given you an idea as to how easy it is to get going with Spring MVC, and how some of the core concepts in the framework tie together. It may also be appropriate at this point to mention that in the interest of making it easier to understand the core concepts, there are a few (hopefully very obvious) areas in my sample that are not handled the way they would be in a larger or production application, as an example, the hard-coding of messages inside Java code, or some of the package organization. Now I'd like to encourage you to learn more about and experiment with Spring MVC's full featureset and comprehensive capabilities in areas such mapping of requests to controllers and methods, data binding and validation, locale and theme support, and general ability to be customized to handle pretty much all web tier use cases that fit the action response model. One valuable resource for you in this learning process is Keith Donald's Spring MVC 3 Showcase, which includes working code showing most of the capabilities of Spring MVC, that you can easily load into SpringSource Tool Suite (STS) or another Eclipse environment and experiment with. As an aside, if you are not familiar with STS, I should mention that it's a great tool for experimenting with the Spring set of technologies, because of its great support for Spring and features like the out of the box project templates. In this short video recording, I show how to get going with a new Spring MVC application via an STS template.
Appendix Dependencies
The code above should work regardless of which build system you use (these days, I generally prefer Gradle or Maven). Here is a relatively minimal sample Maven POM file to build the above project, which may be used as a base, or to gain an understanding of what dependencies are needed. It's actually not quite as minimal as it could be, since I've explicitly switched out commons-logging for SLF4J, and added some optional repositories and Maven plugins. The only non-obvious item may be the need for CGLIB, which is an optional dependency needed by Spring when @Configuration is used.
< ? x m lv e r s i o n = " 1 . 0 "e n c o d i n g = " U T F 8 " ? > < p r o j e c tx m l n s = " h t t p : / / m a v e n . a p a c h e . o r g / P O M / 4 . 0 . 0 "x m l n s : x s i = " h t t p : / / w w w . w 3 . o r g / 2 0 0 1 / X M L S c h e m a i n s t a n c e " x s i : s c h e m a L o c a t i o n = " h t t p : / / m a v e n . a p a c h e . o r g / P O M / 4 . 0 . 0h t t p : / / m a v e n . a p a c h e . o r g / m a v e n v 4 _ 0 _ 0 . x s d " > < m o d e l V e r s i o n > 4 . 0 . 0 < / m o d e l V e r s i o n > < g r o u p I d > x y z . s a m p l e < / g r o u p I d > < a r t i f a c t I d > b a r e m v c < / a r t i f a c t I d > < n a m e > S p r r i n gM V Cs a m p l ep r o j e c t < / n a m e > < p a c k a g i n g > w a r < / p a c k a g i n g > < v e r s i o n > 1 . 0 . 0 B U I L D S N A P S H O T < / v e r s i o n > < p r o p e r t i e s > < j a v a v e r s i o n > 1 . 6 < / j a v a v e r s i o n > < o r g . s p r i n g f r a m e w o r k v e r s i o n > 3 . 0 . 6 . R E L E A S E < / o r g . s p r i n g f r a m e w o r k v e r s i o n > < o r g . s l f 4 j v e r s i o n > 1 . 6 . 1 < / o r g . s l f 4 j v e r s i o n > < / p r o p e r t i e s > < d e p e n d e n c i e s > < ! -S p r i n g> < d e p e n d e n c y > < g r o u p I d > o r g . s p r i n g f r a m e w o r k < / g r o u p I d > < a r t i f a c t I d > s p r i n g c o n t e x t < / a r t i f a c t I d > < v e r s i o n > $ { o r g . s p r i n g f r a m e w o r k v e r s i o n } < / v e r s i o n > < e x c l u s i o n s > < ! -E x c l u d eC o m m o n sL o g g i n gi nf a v o ro fS L F 4 j> < e x c l u s i o n > < g r o u p I d > c o m m o n s l o g g i n g < / g r o u p I d > < a r t i f a c t I d > c o m m o n s l o g g i n g < / a r t i f a c t I d > < / e x c l u s i o n > < / e x c l u s i o n s > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s p r i n g f r a m e w o r k < / g r o u p I d > < a r t i f a c t I d > s p r i n g w e b m v c < / a r t i f a c t I d > < v e r s i o n > $ { o r g . s p r i n g f r a m e w o r k v e r s i o n } < / v e r s i o n > < / d e p e n d e n c y >
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
9/12
8/9/13
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
< g r o u p I d > c g l i b < / g r o u p I d > < a r t i f a c t I d > c g l i b n o d e p < / a r t i f a c t I d > < v e r s i o n > 2 . 2 < / v e r s i o n > < / d e p e n d e n c y >
< ! -L o g g i n g> < d e p e n d e n c y > < g r o u p I d > o r g . s l f 4 j < / g r o u p I d > < a r t i f a c t I d > s l f 4 j a p i < / a r t i f a c t I d > < v e r s i o n > $ { o r g . s l f 4 j v e r s i o n } < / v e r s i o n > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s l f 4 j < / g r o u p I d > < a r t i f a c t I d > j c l o v e r s l f 4 j < / a r t i f a c t I d > < v e r s i o n > $ { o r g . s l f 4 j v e r s i o n } < / v e r s i o n > < s c o p e > r u n t i m e < / s c o p e > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s l f 4 j < / g r o u p I d > < a r t i f a c t I d > s l f 4 j l o g 4 j 1 2 < / a r t i f a c t I d > < v e r s i o n > $ { o r g . s l f 4 j v e r s i o n } < / v e r s i o n > < s c o p e > r u n t i m e < / s c o p e > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > l o g 4 j < / g r o u p I d > < a r t i f a c t I d > l o g 4 j < / a r t i f a c t I d > < v e r s i o n > 1 . 2 . 1 6 < / v e r s i o n > < s c o p e > r u n t i m e < / s c o p e > < / d e p e n d e n c y >
< ! -@ I n j e c t> < d e p e n d e n c y > < g r o u p I d > j a v a x . i n j e c t < / g r o u p I d > < a r t i f a c t I d > j a v a x . i n j e c t < / a r t i f a c t I d > < v e r s i o n > 1 < / v e r s i o n > < / d e p e n d e n c y >
< ! -S e r v l e t> < d e p e n d e n c y > < g r o u p I d > j a v a x . s e r v l e t < / g r o u p I d > < a r t i f a c t I d > s e r v l e t a p i < / a r t i f a c t I d > < v e r s i o n > 2 . 5 < / v e r s i o n > < s c o p e > p r o v i d e d < / s c o p e > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > j a v a x . s e r v l e t . j s p < / g r o u p I d > < a r t i f a c t I d > j s p a p i < / a r t i f a c t I d > < v e r s i o n > 2 . 1 < / v e r s i o n > < s c o p e > p r o v i d e d < / s c o p e > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > j a v a x . s e r v l e t < / g r o u p I d > < a r t i f a c t I d > j s t l < / a r t i f a c t I d > < v e r s i o n > 1 . 2 < / v e r s i o n > < / d e p e n d e n c y >
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
10/12
8/9/13
< ! -T e s t> < d e p e n d e n c y >
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
< g r o u p I d > j u n i t < / g r o u p I d > < a r t i f a c t I d > j u n i t < / a r t i f a c t I d > < v e r s i o n > 4 . 7 < / v e r s i o n > < s c o p e > t e s t < / s c o p e > < / d e p e n d e n c y >
< / d e p e n d e n c i e s > < r e p o s i t o r i e s > < r e p o s i t o r y > < i d > o r g . s p r i n g f r a m e w o r k . m a v e n . r e l e a s e < / i d > < n a m e > S p r i n gM a v e nR e l e a s eR e p o s i t o r y < / n a m e > < u r l > h t t p : / / m a v e n . s p r i n g f r a m e w o r k . o r g / r e l e a s e < / u r l > < r e l e a s e s > < e n a b l e d > t r u e < / e n a b l e d > < / r e l e a s e s > < s n a p s h o t s > < e n a b l e d > f a l s e < / e n a b l e d > < / s n a p s h o t s > < / r e p o s i t o r y > < ! -F o rt e s t i n ga g a i n s tl a t e s tS p r i n gs n a p s h o t s> < r e p o s i t o r y > < i d > o r g . s p r i n g f r a m e w o r k . m a v e n . s n a p s h o t < / i d > < n a m e > S p r i n gM a v e nS n a p s h o tR e p o s i t o r y < / n a m e > < u r l > h t t p : / / m a v e n . s p r i n g f r a m e w o r k . o r g / s n a p s h o t < / u r l > < r e l e a s e s > < e n a b l e d > f a l s e < / e n a b l e d > < / r e l e a s e s > < s n a p s h o t s > < e n a b l e d > t r u e < / e n a b l e d > < / s n a p s h o t s > < / r e p o s i t o r y > < ! -F o rd e v e l o p i n ga g a i n s tl a t e s tS p r i n gm i l e s t o n e s> < r e p o s i t o r y > < i d > o r g . s p r i n g f r a m e w o r k . m a v e n . m i l e s t o n e < / i d > < n a m e > S p r i n gM a v e nM i l e s t o n eR e p o s i t o r y < / n a m e > < u r l > h t t p : / / m a v e n . s p r i n g f r a m e w o r k . o r g / m i l e s t o n e < / u r l > < s n a p s h o t s > < e n a b l e d > f a l s e < / e n a b l e d > < / s n a p s h o t s > < / r e p o s i t o r y > < / r e p o s i t o r i e s > < b u i l d > < p l u g i n s > < p l u g i n > < g r o u p I d > o r g . a p a c h e . m a v e n . p l u g i n s < / g r o u p I d > < a r t i f a c t I d > m a v e n c o m p i l e r p l u g i n < / a r t i f a c t I d > < c o n f i g u r a t i o n > < s o u r c e > $ { j a v a v e r s i o n } < / s o u r c e > < t a r g e t > $ { j a v a v e r s i o n } < / t a r g e t > < / c o n f i g u r a t i o n > < / p l u g i n > < p l u g i n > < g r o u p I d > o r g . a p a c h e . m a v e n . p l u g i n s < / g r o u p I d > < a r t i f a c t I d > m a v e n w a r p l u g i n < / a r t i f a c t I d > < c o n f i g u r a t i o n > < w a r N a m e > b a r e m v c < / w a r N a m e > < / c o n f i g u r a t i o n > < / p l u g i n > < p l u g i n > < g r o u p I d > o r g . c o d e h a u s . m o j o < / g r o u p I d > < a r t i f a c t I d > t o m c a t m a v e n p l u g i n < / a r t i f a c t I d > < v e r s i o n > 1 . 1 < / v e r s i o n > < / p l u g i n > < / p l u g i n s >
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
11/12
8/9/13
< / b u i l d > < / p r o j e c t >
Green Beans: Getting Started with Spring MVC | SpringSource Team Blog
SIMILAR POSTS
Maven PAR Plugin 1.0.0.M1 First Eclipse Gemini Blueprint Milestone Ships Obtaining Spring 3 Artifacts with Maven Migrating to Spring 3.1 and Hibernate 4.1 Spring Security Java Config Preview: Introduction
blog.springsource.com/2011/01/04/green-beans-getting-started-with-spring-mvc/
12/12