Spring MVC Framework
In Short :-

In Short :-
Spring MVC is
part of Web module of spring framework. Spring MVC mainly divided into 3
things.
2)V-view
3)C-Controller.
FLOW
In Spring MVC dispatcher servlet behaves like a front controller which
takes all incoming request and dispatch to related controller and controllers
are known as handler. And then handler will process the request and sent back
the data in the form of Model to front controller and then after front
controller select the particular view with the help of view resolver and send
response back to client.
1) Introduction
The Spring MVC provides rich
functionality for building robust Web Applications and it is available as
a separate module in the Distribution. As a pre-requisite, readers are advised
to go through the introductory article on Spring Framework Introduction to Spring
Framework. The Spring MVC Framework is architected and
designed in such a way that every piece of logic and functionality is highly
configurable. Also Spring can integrate effortlessly with other popular Web
Frameworks like Struts, WebWork, Java Server Faces and Tapestry. It means that you
can even instruct Spring to use any one of the Web Frameworks. More than that
Spring is not tightly coupled with Servlets or Jsp to render the View to the
Clients. Integration with other View technologies like Velocity, Freemarker, Excel or Pdf is also possible now.
This article provides an introduction over the various components that are
available in the Spring MVC for the Web Tier.
Specifically the major Core Components like Dispatcher Servlet, Handler
Mappings, Controller, Model, View and View
Resolver along with the appropriate Api are discussed briefly. Finally
the article will conclude by presenting a Sample Application.
2) The Spring Workflow
Before
taking a look over the various Components that are involved in the Spring MVC
Framework, let us have a look on the style of Spring Work Flow.
1. The Client requests
for a Resource in the Web
Application.
2. The Spring
Front Controller, which is implemented as a Servlet, will intercept the Request
and then will try to find out the appropriate Handler Mappings.
3. The Handle
Mappings is used to map a request from the Client to its Controller
object by browsing over the various Controllers defined in the Configuration
file.
4. With the help of Handler
Adapters, the Dispatcher Servlet will dispatch the Request to the
Controller.
5. The Controller
processes the Client Request and returns the Model and the View in the form of ModelAndView object back to the
Front Controller.
6. The Front
Controller then tries to resolve the actual View (which may be Jsp,
Velocity or Free marker) by consulting the View Resolver object.
7. Then the selected View
is rendered back to the Client.
Let
us look into the various Core Components that make up the Spring Web Tier.
Following are the components covered in the next subsequent sections.
3) Dispatcher Servlet
The Dispatcher
Servlet as represented by org.springframework.web.servlet.
DispatcherServlet, follows the Front Controller Design
Pattern for handling Client Requests. It means that whatever Url comes
from the Client, this Servlet will intercept the Client Request before passing
the Request Object to the Controller. The Web Configuration file should be given
definition in such a way that this Dispatcher Servlet should be invoked for
Client Requests.
Following is the definition given in the web.xml to invoke Spring’s Dispatcher Servlet.
web.xml
Following is the definition given in the web.xml to invoke Spring’s Dispatcher Servlet.
web.xml
1
|
<?xml version='1.0' encoding='UTF-8'?>
|
|
2
|
<web-app version='2.4'>
|
3
|
||
4
|
<servlet>
|
5
|
<servlet-name>dispatcher</servlet-name>
|
|
6
|
<servlet-class>
|
7
|
org.springframework.web.servlet.DispatcherServlet
|
|
8
|
</servlet-class>
|
9
|
<load-on-startup>2</load-on-startup>
|
||
10
|
</servlet>
|
||
11
|
||
12
|
<servlet-mapping>
|
13
|
<servlet-name>dispatcher</servlet-name>
|
|
14
|
<url-pattern>*.*</url-pattern>
|
15
|
</servlet-mapping>
|
|
16
|
17
|
</web-app>
|
Look
into the definition of servlet-mapping tag. It tells that whatever be the Client Request (represented
by *.* meaning any Url with any extension), invoke the Servlet by name 'dispatcher'. In our case, the
‘dispatcher’ servlet is nothing but an instance of type 'org.springframework.web.servlet.DispatcherServlet'.
Closing associated term with the Dispatcher Servlet is the Application Context. An Application Context usually represents a set of Configuration Files that are used to provide Configuration Information to the Application. The Application Context is a Xml file that contain various Bean Definitions. By default the Dispatcher Servlet will try to look for a file by name <servlet-name>-servlet.xml in the WEB-INF directory. So, in our case the Servlet will look for a file name called dispatcher-servlet.xml file in the WEB-INF directory.
It is wise sometimes to split all the Configuration information across multiple Configuration Files. In such a case we have to depend on a Listener Servlet called Context Loader represented by org.springframework.web.context.ContextLoaderListener.
Closing associated term with the Dispatcher Servlet is the Application Context. An Application Context usually represents a set of Configuration Files that are used to provide Configuration Information to the Application. The Application Context is a Xml file that contain various Bean Definitions. By default the Dispatcher Servlet will try to look for a file by name <servlet-name>-servlet.xml in the WEB-INF directory. So, in our case the Servlet will look for a file name called dispatcher-servlet.xml file in the WEB-INF directory.
It is wise sometimes to split all the Configuration information across multiple Configuration Files. In such a case we have to depend on a Listener Servlet called Context Loader represented by org.springframework.web.context.ContextLoaderListener.
1
|
<web-app>
|
|
2
|
3
|
<listener>
|
|
4
|
<listener-class>
|
5
|
org.springframework.web.context.ContextLoaderListener
|
|
6
|
</listener-class>
|
7
|
</listener>
|
|
8
|
9
|
</web-app>
|
By
default, this Context Listener will try to look for the Configuration File by
name
'applicationContext.xml' in the '/WEB-INF' directory. But with the help of the parameter 'contextConfigLocation' the default location can be overridden. Even multiple Configuration Files each containing separate piece of Information is also possible.
web.xml
'applicationContext.xml' in the '/WEB-INF' directory. But with the help of the parameter 'contextConfigLocation' the default location can be overridden. Even multiple Configuration Files each containing separate piece of Information is also possible.
web.xml
1
|
<?xml version='1.0' encoding='UTF-8'?>
|
|
2
|
<web-app version='2.4'>
|
3
|
||
4
|
<listener>
|
5
|
<listener-class>
|
|
6
|
org.springframework.web.context.ContextLoaderListener
|
7
|
</listener-class>
|
|
8
|
</listener>
|
9
|
|||
10
|
<context-param>
|
||
11
|
<param-name>contextConfigLocation</param-name>
|
|
12
|
<param-value>/WEB-INF/contacts.xml,
/WEB-INF/resources.xml</param-value>
|
13
|
</context-param>
|
|
14
|
15
|
</web-app>
|
The
above definition instructs the Framework to look and load for the Configuration
Files by name 'contacts.xml' and 'resources.xml' in the WEB-INF directory.
4) Handler Mappings
When
the Client Request reaches the Dispatcher Servlet, the Dispatcher
Servlet tries to find the appropriate Handler Mapping Object to map between
the Request and the Handling Object. A Handler Mapping provides an abstract
way that tell how the Client’s Url has to be mapped to the Handlers. Four
concrete variation of Handler Mapping are available. They are defined as
follows
·
BeanNameUrl HandlerMapping
·
CommonsPathMap HandlerMapping
·
ControllerClassName HandlerMapping
·
SimpleUrl HandlerMapping
All
the above Handler Mapping objects are represented as BeanNameUrlHandlerMapping, CommonsPathMapHandlerMapping, ControllerClassNameHandlerMapping and SimpleUrlHandlerMapping in the org.springframework.web.servlet package respectively.
Let us see the functionalities and the differences in usage one by one.
4.1) BeanNameUrl
HandlerMapping
This
is the simplest of the Handler Mapping and it is used to map
the Url that comes from the Clients directly to the Bean Object. In the later
section, we will see that the Bean is nothing but a Controller object. For
example, consider that the following are the valid Url in a Web Application
that a Client Application can request for.
1
|
||
2
|
3
|
||
4
|
5
|
||
6
|
Note
that the Url (excluding the Application Context) in the above cases are 'showAllMails', 'composeMail' and 'deleteMail'. This means that the
Framework will look for Bean Definitions with Identifiers ‘showAllMails’,
‘composeMail’ and ‘deleteMail’. Consider the following Xml code snippet in the
Configuration file,
1
|
<beans>
|
|
2
|
3
|
<bean name='/showAllMails.jsp'
|
|
4
|
class='com.javabeat.net.ShowAllMailsController'>
|
5
|
</bean>
|
|
6
|
7
|
<bean name='/composeMail.jsp'
|
|
8
|
class='com.javabeat.net.ComposeMailController'>
|
9
|
</bean>
|
||
10
|
|||
11
|
<bean name='/ deleteMail.jsp'
|
|
12
|
class='com.javabeat.net.DeleteMailController'>
|
13
|
</bean>
|
|
14
|
15
|
</beans>
|
So,
in BeanNameUrl
Handler Mapping, the Url of the Client is directly mapped to the Controller. To
enable this kind of Handler Mapping in the Application, the Configuration file
should have a similar kind of definition like the following,
1
|
<beans>
|
|
2
|
3
|
…
|
|
4
|
<bean id='beanNameUrl'
|
5
|
class='org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping'/>
|
|
6
|
…
|
7
|
||
8
|
</beans>
|
4.2) CommonsPathMap
HandlerMapping
This
is a rarely used Handler Mapping in which case, the name of the Url to which
the Controller has to be mapped is specified directly in the Source file of the
Controller. Considering the previous example, if we want to map ‘showAllMails’,
‘composeMail’ and ‘deleteMail’ to Controllers namely ShowAllMailsController, ComposeMailController and DeleteMailController, then the mapping
information must be specified in the form of meta-data in the source files inside the Javadoc
comments. Consider the following Controller Definitions,
1
|
/**
|
|
2
|
*@@
org.springframework.web.servlet.handler.commonsattributes.
|
3
|
*PathMap('/showAllMails.jsp')
|
|
4
|
*/
|
5
|
public class ShowAllMailsController{
|
|
6
|
}
|
7
|
||
8
|
/**
|
9
|
*@@
org.springframework.web.servlet.handler.commonsattributes.
|
||
10
|
*PathMap('/composeMail.jsp')
|
||
11
|
*/
|
|
12
|
public class ComposeMailController{
|
13
|
}
|
|
14
|
15
|
/**
|
|
16
|
*@@
org.springframework.web.servlet.handler.commonsattributes.
|
17
|
*PathMap('/deleteMail.jsp')
|
|
18
|
*/
|
19
|
public class DeleteMailController {
|
|
20
|
}
|
The
attribute must point to org.springframework.web.servlet.handler.commonsattributes.PathMap. By defining
Controllers in this way, one more additional compilation step is needed. That
is to make the availability of this attribute in the Class files, this Java
Source has to be compiled with the Commons Attribute Compiler which comes along with
the Spring Distribution. As before, to enable this kind of mapping , the
Configuration File should have an entry similar to this,
1
|
<beans>
|
|
2
|
3
|
<bean
id='metaHandlerMapping' class='org.springframework.web.servlet.handler.
|
|
4
|
metadata.CommonsPathMapHandlerMapping'/>
|
5
|
||
6
|
</beans>
|
7
|
4.3)
ControllerClassName HandlerMapping
In
this kind of Handler Mapping, the name of the Controller is taking directly
from the Url itself with slight modifications. For example, let us assume that
the Client request ends with Url as shown below,
1
|
http://myserver.com/emailApp/showInbox.jsp
|
|
2
|
3
|
http://myserver.com/emailApp/showDeletedItems.jsp
|
And
as such, we have a Controller definition by name ShowController as follows,
ShowController.java
ShowController.java
1
|
public class ShowController{
|
|
2
|
}
|
Also
the Configuration file is made to activate this kind of Handler Mapping by
making the following definition,
1
|
<beans>
|
|
2
|
3
|
<bean id='controllerClassName' class='org.springframework.web.servlet.handler.
|
||
4
|
metadata.ControllerClassNameHandlerMapping'/>
|
||
5
|
||
6
|
</beans>
|
The
first thing the Framework does it, it will traverse through the List of
Controllers defined in the Configuration File and perform these actions. For
the Controller ShowController, then Framework will remove the Controller String
and then lowercase the first letter. In our case the string now becomes show.
Now whatever Client Request matches the pattern /show*, then the ShowController will be invoked.
4.4) SimpleUrl
HandlerMapping
This
is the Simplest of all the Handler Mappings as it directly maps the Client
Request to some Controller object. Consider the following Configuration File,
1
|
<bean id='simpleUrlMapping'
|
|
2
|
class='org.springframework.web.servlet.handler.SimpleUrlHandlerMapping'>
|
3
|
||
4
|
<property name='mappings'>
|
5
|
<props>
|
|
6
|
<prop key='/showAllMails.jsp'>showController</prop>
|
7
|
<prop key='/composeMail.jsp'>composeController</prop>
|
|
8
|
<prop key='/deleteMail.jsp'>deleteController</prop>
|
9
|
</props>
|
|
10
|
</property>
|
|
11
|
||
12
|
</bean>
|
The
set of mappings is encapsulated in the 'property' tag with each defined in a 'prop' element with the 'key' attribute being the
Url, the value being the Identifier of the Controller Objects. Note that the
Beans for the above Identifiers should be defined somewhere in the
Configuration File.
5) Handler Adapters
It
is important to understand that the Spring Framework is so flexible enough to
define what Components should be delegated the Request once the Dispatcher
Servlet finds the appropriate Handler Mapping. This is achieved in
the form of Handler Adapters. If you remember in
the Spring Work flow section, that it is mentioned once the Dispatcher Servlet
chooses the appropriate Handler Mapping, the Request is then
forwarded to the Controller object that is defined in the Configuration File.
This is the default case. And this so happens because the Default
Handler Adapter is Simple Controller Handler Adapter (represented by org.springframework.web.servlet.SimpleControllerHandlerAdapter), which will do the
job of the Forwarding the Request from the Dispatcher to the Controller object.
Other types of Handler Adapters are Throwaway Controller HandlerAdapter (org.springframework.web.servlet.ThrowawayControllerHandlerAdapter) and SimpleServlet HandlerAdapter (org.springframework.web.servlet.SimpleServletHandlerAdapter). The Throwaway Controller HandlerAdapter, for example, carries the Request from the Dispatcher Servlet to the Throwaway Controller (discussed later in the section on Controllers) and Simple Servlet Handler Adapter will carry forward the Request from the Dispatcher Servlet to a Servlet thereby making the Servlet.service() method to be invoked.
If, for example, you don’t want the default Simple Controller Handler Adapter, then you have to redefine the Configuration file with the similar kind of information as shown below,
Other types of Handler Adapters are Throwaway Controller HandlerAdapter (org.springframework.web.servlet.ThrowawayControllerHandlerAdapter) and SimpleServlet HandlerAdapter (org.springframework.web.servlet.SimpleServletHandlerAdapter). The Throwaway Controller HandlerAdapter, for example, carries the Request from the Dispatcher Servlet to the Throwaway Controller (discussed later in the section on Controllers) and Simple Servlet Handler Adapter will carry forward the Request from the Dispatcher Servlet to a Servlet thereby making the Servlet.service() method to be invoked.
If, for example, you don’t want the default Simple Controller Handler Adapter, then you have to redefine the Configuration file with the similar kind of information as shown below,
1
|
<bean id='throwawayHandler' class =
'org.springframework.web.servlet.mvc.throwaway.
|
|
2
|
ThrowawayControllerHandlerAdapter'/>
|
3
|
||
4
|
or
|
5
|
||
6
|
<bean id='throwawayHandler' class='org.springframework.web.servlet.mvc.throwaway.
|
7
|
SimpleServletHandlerAdapter'/>
|
|
8
|
Even,
it is possible to write a Custom Handler Adapter by implementing the HandlerAdapter interface available in
the org.springframework.web.servlet package.
6) Controller
Controllers
are components that are being called by the Dispatcher Servlet for doing any
kind of Business Logic. Spring Distribution already comes with a variety of Controller
Components each doing a specific purpose. All Controller Components in
Spring implement the org.springframework.web.servlet.mvc.Controller interface. This
section aimed to provide the commonly used Controllers in the Spring Framework.
The following are the Controller Components available in the Spring
Distribution.
·
SimpleFormController
·
AbstractController
·
AbstractCommandController
·
CancellableFormController
·
AbstractCommandController
·
MultiActionController
·
ParameterizableViewController
·
ServletForwardingController
·
ServletWrappingController
·
UrlFilenameViewController
The
following section covers only on AbstractController, AbstractCommandController, SimpleFormController and CancellableFormController in detail.
6.1) Abstract
Controller
If
one wants to implement Custom Controller Component right from the
scratch, then instead of implementing the Controller interface, extending AbstractController can be preferred as it
provides the basic support for the GET and the POST methods. It is advised
that only for simple purpose, this type of extensions should be used. The
purpose may be as simple as returning a resource to the Client upon request
without having the need to examine the Request Parameters or other Stuffs. For
example, consider the following piece of code,
MySimpleController.java
MySimpleController.java
1
|
public class MySimpleController extends AbstractController{
|
|
2
|
3
|
public ModelAndView
handleRequestInternal(HttpServletRequest request,
|
|
4
|
HttpServletResponse
response){
|
5
|
||
6
|
return new ModelAndView('myView');
|
7
|
||
8
|
}
|
9
|
}
|
Note
that the Dispatcher Servlet will call the handleRequest() method by passing the Request and the Response
parameters. The implementation just returns a ModelAndView (discussed later) object with myView being the
logical view name. There are Components called View Resolvers whose job is to
provide a mapping between the Logical View Name and the actual Physical
Location of the View Resource. For the time being, assume that somehow,
myView is mapped to myView.jsp. So, whenever the Dispatcher Servlet invokes this
MySimpleController object, finally myView.jsp will be rendered back to the
Client.
6.2) Abstract Command
Controller
The
concept of Command Controller comes into picture
when the Business Logic depends upon the values that are submitted by the User.
Instead of depending on the Servlet Api to get the Request Parameter Values and
other session Objects, we can depend on this Abstract Command Controller to take those pieces
of Information. For example consider the following code snippet which has a
simple business logic telling that, depending on the existence of username,
display the form success.jsp or failure.jsp
MySimpleController.java
MySimpleController.java
1
|
public class MySimpleController extends AbstractCommandController{
|
|
2
|
3
|
public MySimpleController(){
|
|
4
|
setCommandClass(UserInfo.class);
|
5
|
}
|
|
6
|
7
|
public ModelAndView
handle(HttpServletRequest request, HttpServletResponse response,
|
|
8
|
Object
command){
|
9
|
|||
10
|
UserInfo
userInfo = (UserInfo)command;
|
||
11
|
if ( exists(userInfo.getUserName){
|
|
12
|
return new ModelAndView('success');
|
13
|
}else{
|
|
14
|
return new ModelAndView('failure');
|
15
|
}
|
|
16
|
}
|
17
|
||
18
|
private boolean exits(String username){
|
19
|
//
Some logic here.
|
|
20
|
}
|
21
|
}
|
Note
that the Client Parameters (username , in this
case) is encapsulated in a simple Class called UserInfo which is given below. The value given by the
Client for the username field will be directly mapped to the property called
username in the UserInfo. In the Constructor of the MySimpleController class, we have
mentioned the name of the Command Class which is going to hold the Client
Request Parameters by calling the setCommandClass() method. Also note that
in the case of Command Controller, the method that will be called by the
Dispatcher Servlet will be handle() which is passed with the Command object apart from the Request
and the Response objects.
UserInfo.java
UserInfo.java
public class UserInfo{
|
||
2
|
3
|
private String username;
|
|
4
|
//
Getters and Setters here.
|
5
|
||
6
|
}
|
6.3) Simple Form
Controller
Asking
the User to fill in a Form containing various information and submitting the
form normally happens in almost every Web Application. The Simple Form Controller is exactly used for
that purpose. Let us give a simple example to illustrate this. Assume that upon
Client Request a page called empInfo.jsp is rendered to the client containing empName, empAge and empSalary fields. Upon
successful completion a Jsp Page called empSuccess.jsp is displayed back to the Client. Now let us
see how we can make use of the Simple Form Controller to achieve this kind functionality.
The very first thing is that, to collect the Client Input Values, a Command object which contains getter and setters must be defined. Following the skeleton of the class called EmpInfo.
EmpInfo.java
The very first thing is that, to collect the Client Input Values, a Command object which contains getter and setters must be defined. Following the skeleton of the class called EmpInfo.
EmpInfo.java
1
|
public class EmpInfo{
|
|
2
|
3
|
private String empName;
|
|
4
|
private int empAge;
|
5
|
private double empSalary;
|
|
6
|
7
|
//
Getters and setters for the above properties.
|
|
8
|
9
|
}
|
The
next thing is to write a class that extends SimpleFormController. But this
time, the doSubmitAction() method should be overridden. This is the method that will be
called when the Client submits the form. Following is the definition of the
Controller class.
EmpFormController.java
EmpFormController.java
1
|
public class EmpFormController extends SimpleFormController{
|
|
2
|
3
|
public EmpFormController(){
|
|
4
|
setCommandClass(EmpInfo.class);
|
5
|
}
|
|
6
|
7
|
public void doSubmitAction(Object command){
|
|
8
|
EmpInfo
info = (EmpInfo)command;
|
9
|
process(info);
|
||
10
|
}
|
||
11
|
||
12
|
private void process(EmpInfo info){
|
13
|
//Do
some processing with this object.
|
|
14
|
}
|
15
|
}
|
|
16
|
As
we mentioned previously, the form that collects information from the Client is empInfo.jsp and upon successful
submission the view empSuccess.jsp should be displayed. This information is externalized from the
Controller class and it is maintained in the Configuration File like the
following,
1
|
<bean id = 'empForm' class='EmpFormController'>
|
|
2
|
3
|
<property name='formView'>
|
|
4
|
<value>empInfo</value>
|
5
|
</property>
|
|
6
|
7
|
<property name='successView'>
|
|
8
|
<value>empSuccess</value>
|
9
|
</property>
|
||
10
|
|||
11
|
</bean>
|
Note
the two property names 'formView' and 'successView' along with the values 'empInfo' and 'empSuccess'. These properties represent the initial View
to be displayed and the final view (after successful Form submission) to be
rendered to the Client.
6.4) Cancellable
FormController
If
you carefully notice with the implementation of Simple Form Controller, there
are ways to provide the Initial and the Successful View to the Clients. But
what happens when the Form is cancelled by the User? Who will process the
Cancel operation of the Form?
The above issues can be given immediate solution with the usage of Cancellable FormController. The good thing is that Cancellable FormController extends SimpleForm Controller so that all the functionalities are visible to this Controller also. Suppose say that the User clicks the cancel button, the Framework will check in the Request parameter for a key with name 'cancelParamKey'. If it is so, then it will call the onCancel() method. Consider the following definition,
MyCompleteFormController.java
The above issues can be given immediate solution with the usage of Cancellable FormController. The good thing is that Cancellable FormController extends SimpleForm Controller so that all the functionalities are visible to this Controller also. Suppose say that the User clicks the cancel button, the Framework will check in the Request parameter for a key with name 'cancelParamKey'. If it is so, then it will call the onCancel() method. Consider the following definition,
MyCompleteFormController.java
1
|
public class MyCompleteFormController extends CancellableFormController{
|
|
2
|
3
|
public ModelAndView onCancel(){
|
|
4
|
return new ModelAndView('cancelView');
|
5
|
}
|
|
6
|
}
|
7) Model And View
Model and View (represented by the class org.springframework.web.servlet.ModelAndView) is returned by the
Controller object back to the Dispatcher Servlet. This class is just a
Container class for holding the Model and the View information. The Mode object
represents some piece of information that can be used by the View to display
the information. Both these Objects are given high degree of abstraction in the
Spring Framework.
Any kind of View Technology (org.springframework.web.servlet.View) can be plugged into the Framework with ease. For example, Excel, Jasper Reports, Pdf, Xslt, Free Marker, Html, Tiles, Velocity etc. are the supported Frameworks as of now. The Model object (represented by org.springframework.ui.ModelMap) is internally maintained as a Map for storing the Information.
Following are the ways to Construct the Model and the View object.
Any kind of View Technology (org.springframework.web.servlet.View) can be plugged into the Framework with ease. For example, Excel, Jasper Reports, Pdf, Xslt, Free Marker, Html, Tiles, Velocity etc. are the supported Frameworks as of now. The Model object (represented by org.springframework.ui.ModelMap) is internally maintained as a Map for storing the Information.
Following are the ways to Construct the Model and the View object.
1
|
View pdfView = …;
|
|
2
|
Map modelData = new HashMap();
|
3
|
||
4
|
ModelAndView mv1 = new ModelAndView(pdfView, modelData);
|
The
above constructs a ModelAndView object by passing the actual View object along with the Model
object. Now consider the following code,
1
|
ModelAndView mv1 = new ModelAndView('myView', someData);
|
Note,
in the above example, a string with “myView” is passed for the View. This way
of specifying a View is called a Logical View. It means that myView either can point to
something called myView.jsp or myView.pdf or myView.xml. The Physical View Location corresponding to the Logical View can be made
configurable in the Configuration File.
8) View Resolver
In
the previous section, we talked about Logical View and the Physical View Location for the Logical View.
The mapping between the Logical name and the Physical View Location is taken
care by the View Resolver object. Without any surprise, Spring comes
with a set of Built-In Spring Resolvers. It is even possible to write Custom View Resolvers by implementing the org.springframework.web.servlet.ViewResolver interface. Following
are the available View Resolvers in the Spring Distribution.
·
BeanNameViewResolver
·
FreeMarkerViewResolver
·
InternalResourceViewResolver
·
JasperReportsViewResolver
·
ResourceBundleViewResolver
·
UrlBasedViewResolver
·
VelocityLayoutViewResolver
·
VelocityViewResolver
·
XmlViewResolver
·
XsltViewResolver
The
following section concentrates only on Internal Resource View Resolver and Bean Name View Resolver in detail.
8.1) Internal Resource
View Resolver
The Internal Resource View
Resolver will try to map the Logical name of the Resource as returned by
the Controller object in the form of ModelAndView object to the Physical View location. For example,
consider the following class definition which returns different ModelAndView
objects.
MyController.java
MyController.java
1
|
public class MyController {
|
|
2
|
3
|
public ModelAndView handle(){
|
|
4
|
if(condition1()){
|
5
|
return new ModelAndView('myView1');
|
|
6
|
}else if (condition2()){
|
7
|
return new ModelAndView('myView2');
|
|
8
|
}
|
9
|
return new ModelAndView('myView3');
|
||
10
|
}
|
||
11
|
}
|
Assume
that if the Client Request satisfies condition1(), then the view myView.jsp which is present in
the /WEB-INF folder should be
displayed and for the client Requests satisfying condition2() and the other one, myView2.jsp and myView3.jsp should be displayed.
For this to happen, the following entry must be made in the Configuration File,
For this to happen, the following entry must be made in the Configuration File,
1
|
<bean id='viewResolver' class='org.springframework.web.servlet.view.
|
|
2
|
InternalResourceViewResolver'>
|
3
|
||
4
|
<property name='prefix'><value>/WEB-INF/</value></property>
|
5
|
<property name='suffix'><value>.jsp</value></property>
|
|
6
|
7
|
</bean>
|
This
is how the Internal Resource View Resolver will map the Logical
View Name to the physical Location. When the logical View name is myView1, then
it will construct a view name which is the summation of the prefix + the logical
View Name + the suffix, which is going to be /WEB-INF/myView.jsp. The same is the case
for myView2.jsp and myView3.jsp.
8.2) Bean Name View
Resolver
One
of the dis-advantage of using Internal Resource View Resolver is that the name of
the View file (whether it is a Jsp File or the Pdf File) must be present in the
Web Application Context. Dynamically generated View files may not be possible.
In such a case, we may use the Bean Name View Resolver which will dynamically generate View in Pdf or
Excel Formats.
For the example, if the ModelAndView object represents a View by name “pdf” as shown in the following snippet,
For the example, if the ModelAndView object represents a View by name “pdf” as shown in the following snippet,
1
|
return ModelAndView('pdf')
|
And,
if we want to generate the Pdf file, then we should have defined the
Configuration information in the file as follows,
1
|
<bean id='beanNameResolver'
|
|
2
|
class='org.springframework.web.servlet.view.BeanNameViewResolver'/>
|
The
above code configures the Framework to use BeanNameViewResolver. Since the
logical name ‘pdf’ must resolve to a Bean Name, we should define a similar
entry like the following in the Configuration File. Note that, in the following
MyPdfGenerator may be the sub-class of org.springframework.web.servlet.view.document.AbstractPdfView for generating the Pdf
File.
1
|
<bean id = ' pdf ' class = 'MyPdfGenerator'/>
|
9) Sample Application
9.1) Introduction
The
final Section of this article details a Simple Contact Application that has
provisions for Creating, Deleting and Listing Contact Objects. The aim of this
Application is to show the various use of Controller Components like Abstract
Controller, Abstract Command Controller and Form Controller along with
Configuration Information.
9.2) The Web
Descriptor File
As
mentioned previously, since the Dispatcher Servlet acts as an Interceptor for the Client
Request, an entry for the same has to be mentioned in the web.xml file. Follow is the
code snippet for the same,
web.xml
web.xml
1
|
web.xml
|
|
2
|
3
|
<?xml version='1.0' encoding='UTF-8'?>
|
|
4
|
5
|
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
|
6
|
xsi:schemaLocation='http://java.sun.com/xml/ns/j2ee
|
7
|
||
8
|
9
|
|||
10
|
<servlet>
|
||
11
|
<servlet-name>dispatcher</servlet-name>
|
|
12
|
<servlet-class>
|
13
|
org.springframework.web.servlet.DispatcherServlet
|
|
14
|
</servlet-class>
|
15
|
<load-on-startup>2</load-on-startup>
|
|
16
|
</servlet>
|
17
|
||
18
|
<servlet-mapping>
|
19
|
<servlet-name>dispatcher</servlet-name>
|
|
20
|
<url-pattern>*.htm</url-pattern>
|
21
|
</servlet-mapping>
|
|
22
|
23
|
</web-app>
|
|
24
|
9.3) Configuration
File
The
following represents the Configuration File for holding various piece of
Configuration Information. The first thing to note is the type of Handler
Mapping configured. In our case, it is the Bean Name Url Handler Mapping which
means that the Url of the Client is tightly coupled with the class name of the
Bean (Controller). Since all the Jsp files are maintained in the '/WEB/contacts' directory the 'prefix' property is pointing
to '/WEB/contacts'.
For the Create, Delete and List operation on Contacts, three different Controller Components have been defined. They are CreateContactController, DeleteContactController and ListContactsController respectively.
dispatcher-servlet.xml
For the Create, Delete and List operation on Contacts, three different Controller Components have been defined. They are CreateContactController, DeleteContactController and ListContactsController respectively.
dispatcher-servlet.xml
1
|
<?xml version='1.0' encoding='UTF-8' ?>
|
|
2
|
<!DOCTYPE beans
PUBLIC '-//SPRING//DTD BEAN//EN'
|
3
|
||
4
|
<beans>
|
5
|
||
6
|
<bean id='beanNameUrlMapping' class='org.springframework.web.servlet.handler.
|
7
|
BeanNameUrlHandlerMapping'/>
|
|
8
|
9
|
<bean name = '/CreateContact.htm' class='net.javabeat.articles.spring.mvc.
|
||
10
|
contacts.CreateContactController'>
|
||
11
|
||
12
|
<property name='formView'>
|
13
|
<value>CreateContact</value>
|
|
14
|
</property>
|
15
|
<property name='successView'>
|
|
16
|
<value>ContactCreated</value>
|
17
|
</property>
|
|
18
|
19
|
</bean>
|
|
20
|
21
|
<bean name = '/DeleteContact.htm' class=
'net.javabeat.articles.spring.mvc.
|
|
22
|
contacts.DeleteContactController'>
|
23
|
</bean>
|
|
24
|
25
|
<bean name = '/ListContacts.htm' class=
'net.javabeat.articles.spring.mvc.
|
|
26
|
contacts.ListContactsController'>
|
27
|
</bean>
|
|
28
|
29
|
<bean id='viewResolver' class='org.springframework.web.servlet.view.
|
|
30
|
InternalResourceViewResolver'>
|
31
|
<property name='prefix' value='/WEB-INF/contacts/'/>
|
|
32
|
<property name='suffix' value='.jsp' />
|
33
|
</bean>
|
|
34
|
35
|
</beans>
|
9.4) CreateContact and
ContactCreated Jsp Files
The
following is the code for CreateContact.jsp file.
CreateContact.jsp
CreateContact.jsp
1
|
<html>
|
2
|
<head>
|
3
|
<meta http-equiv='Content-Type' content='text/html;
charset=UTF-8'>
|
|
4
|
5
|
<title>Create
a Contact</title>
|
|
6
|
</head>
|
7
|
<body>
|
|
8
|
9
|
<h1>Create
a Contact</h1>
|
||
10
|
|||
11
|
<form name = 'CreateContact' method = 'get''>
|
|
12
|
<input type = 'text' name = 'firstname' />
|
13
|
<input type = 'text' name = 'lastname' />
|
|
14
|
<br>
|
15
|
<input type='submit' name = 'Create Contact' value = 'Create Contact'/>
|
|
16
|
</form>
|
17
|
||
18
|
</body>
|
19
|
</html>
|
Note
that since this is the page that will be shown to the user initially, in the
Configuration file, the property 'formView' is pointed to 'CreateContact'. Following is the code for
ContactCreated.jsp. Since this is the View that will be shown after the Form
Submission the property 'successView' is made to point to 'ContactCreated'.
ContactCreated.jsp
ContactCreated.jsp
1
|
<html>
|
|
2
|
<head>
|
3
|
<meta http-equiv = 'Content-Type' content = 'text/html; charset = UTF-8'>
|
|
4
|
<title>Contact
is Created</title>
|
5
|
</head>
|
|
6
|
7
|
<body>
|
|
8
|
9
|
<h1>Contact
is successfully Created</h1>
|
||
10
|
|||
11
|
</body>
|
|
12
|
</html>
|
9.5) DeleteContact.jsp
Following
is the complete listing for DeleteContact.jsp file. Note that this Jsp File is
mapped to DeleteContactController in the Configuration File.
DeleteContact.jsp
DeleteContact.jsp
1
|
<html>
|
2
|
<head>
|
3
|
<meta http-equiv='Content-Type' content='text/html;
charset=UTF-8'>
|
|
4
|
5
|
<title>Delete
Contact</title>
|
|
6
|
</head>
|
7
|
<body>
|
|
8
|
9
|
<h1>Delete
Contact</h1>
|
||
10
|
|||
11
|
<form name = 'DeleteContact' method = 'get'>
|
|
12
|
<input type = 'text' name = 'firstname' />
|
13
|
<br>
|
|
14
|
<input type='submit' name = 'DeleteContact' value = 'Delete Contact'/>
|
15
|
</form>
|
|
16
|
17
|
</body>
|
|
18
|
</html>
|
9.6) ListContacts.jsp
This
page is to list all the existing Contacts that were created before. It should
be noted that the Model Object that holds all the Contact Information in the
form of List is available in the ListContactsController. The Model Information from the Controller
after getting bound to the Request Scope is being taken off from the View in the form
of Expression Language.
Following is the listing for ListContacts.jsp
ListContacts.jsp
Following is the listing for ListContacts.jsp
ListContacts.jsp
1
|
<html>
|
2
|
<head>
|
3
|
<meta http-equiv='Content-Type' content='text/html;
charset=UTF-8'>
|
|
4
|
5
|
<title>Showing
All Contacts</title>
|
|
6
|
</head>
|
7
|
<body>
|
|
8
|
9
|
<h1>Showing
All Contacts</h1>
|
||
10
|
|||
11
|
<p>
The following are the created Contacts </p>
|
|
12
|
13
|
<c:forEach items = '${allContacts}' var='contact'>
|
|
14
|
<c:out value='${contact.firstname}'/><br>
|
15
|
<c:out value='${contact.lastname}'/><br>
|
|
16
|
</c:forEach>
|
17
|
||
18
|
</body>
|
19
|
</html>
|
|
20
|
9.7) Contacts.java
The
following is the Class structure for Contacts.java for encapsulating the
properties firstname and lastname.
Contact.java
Contact.java
1
|
package net.javabeat.articles.spring.mvc.contacts;
|
|
2
|
3
|
public class Contact {
|
|
4
|
5
|
private String firstName;
|
|
6
|
private String lastName;
|
7
|
||
8
|
public Contact() {
|
9
|
}
|
||
10
|
|||
11
|
public Contact(String firstName, String
lastName){
|
|
12
|
this.firstName
= firstName;
|
13
|
this.lastName
= lastName;
|
|
14
|
}
|
15
|
||
16
|
public String getFirstName() {
|
17
|
return firstName;
|
|
18
|
}
|
19
|
||
20
|
public void setFirstName(String firstName) {
|
21
|
this.firstName
= firstName;
|
|
22
|
}
|
23
|
||
24
|
public String getLastName() {
|
25
|
return lastName;
|
|
26
|
}
|
27
|
||
28
|
public void setLastName(String lastName) {
|
29
|
this.lastName
= lastName;
|
|
30
|
}
|
31
|
||
32
|
public int hashCode(){
|
33
|
return firstName.hashCode() +
lastName.hashCode();
|
|
34
|
}
|
35
|
||
36
|
public boolean equals(Object object){
|
37
|
if (object instanceof Contact){
|
|
38
|
Contact
second = (Contact)object;
|
39
|
return (firstName.equals(second.getFirstName())
&&
|
|
40
|
lastName.equals(second.getLastName()));
|
41
|
}
|
|
42
|
return false;
|
43
|
}
|
|
44
|
45
|
public String toString(){
|
|
46
|
return '[First Name = ' + firstName + ', Last Name = ' + lastName + ']';
|
47
|
}
|
|
48
|
}
|
9.8)
ContactService.java
This
simple service class provides functionalities for creating, deleting and
listing the Contact information. All the Controller Components makes use of
this class to achieve their respective functionalities.
ContactService.java
ContactService.java
1
|
package net.javabeat.articles.spring.mvc.contacts;
|
|
2
|
3
|
import java.util.*;
|
|
4
|
5
|
public class ContactService {
|
|
6
|
7
|
private static Map contacts = new HashMap();
|
|
8
|
9
|
public ContactService() {
|
||
10
|
}
|
||
11
|
||
12
|
public static Contact createContact(Contact
contact){
|
13
|
contacts.put(new Integer(contact.hashCode()),
contact);
|
|
14
|
return contact;
|
15
|
}
|
|
16
|
17
|
public static Contact createContact(String
firstName, String lastName){
|
|
18
|
return createContact(new Contact(firstName, lastName));
|
19
|
}
|
|
20
|
21
|
public static boolean deleteContact(String firstName){
|
|
22
|
Iterator
iterator = contacts.entrySet().iterator();
|
23
|
while (iterator.hasNext()){
|
|
24
|
Map.Entry
entry = (Map.Entry)iterator.next();
|
25
|
Contact
contact = (Contact)entry.getValue();
|
|
26
|
if (contact.getFirstName().equals(firstName)){
|
27
|
contacts.remove(new Integer(contact.hashCode()));
|
|
28
|
return true;
|
29
|
}
|
|
30
|
}
|
31
|
return false;
|
|
32
|
}
|
33
|
||
34
|
public static List listContacts(){
|
35
|
return toList(contacts);
|
|
36
|
}
|
37
|
||
38
|
private static List toList(Map contacts){
|
39
|
List
contactList = new ArrayList();
|
|
40
|
Iterator
iterator = contacts.entrySet().iterator();
|
41
|
while (iterator.hasNext()){
|
|
42
|
Map.Entry
entry = (Map.Entry)iterator.next();
|
43
|
Contact
contact = (Contact)entry.getValue();
|
|
44
|
contactList.add(contact);
|
45
|
}
|
|
46
|
return contactList;
|
47
|
}
|
|
48
|
}
|
9.9) Controller
Classes
Following
is the listing for CreateContact Controller. Note that since the Model Information for
creating a contact (for which the Client supplies the firstname and the
lastname parameters) is the Contact class, call has been made in the
Constructor to setCommandClass() by passing the class name of the Contact class.
CreateContactController.java
CreateContactController.java
1
|
package net.javabeat.articles.spring.mvc.contacts;
|
|
2
|
3
|
import org.springframework.web.servlet.mvc.SimpleFormController;
|
|
4
|
5
|
public class CreateContactController extends SimpleFormController{
|
|
6
|
7
|
public CreateContactController() {
|
|
8
|
setCommandClass(Contact.class);
|
9
|
}
|
||
10
|
|||
11
|
public void doSubmitAction(Object command){
|
|
12
|
Contact
contact = (Contact)command;
|
13
|
ContactService.createContact(contact);
|
|
14
|
}
|
15
|
}
|
Note
that the method doSubmitAction() doesn’t return anything because the next Logical View to be
displayed will be taken from the Configuration file which is represented by the
property called 'successView'.
Following two classes are the Controller Components for Deleting and Listing Contacts. Note that in the case of Delete Operation, a Jsp Page (DeletedContact.jsp) containing information telling that the Contact has been Deleted will displayed. But since for the Contact Listing operation, the model information containing a Collection of Contact Objects has to be passed from the Controller to the View and the same is achieved in the 3 argument constructor to ModelAndView.
DeleteContactController.java
Following two classes are the Controller Components for Deleting and Listing Contacts. Note that in the case of Delete Operation, a Jsp Page (DeletedContact.jsp) containing information telling that the Contact has been Deleted will displayed. But since for the Contact Listing operation, the model information containing a Collection of Contact Objects has to be passed from the Controller to the View and the same is achieved in the 3 argument constructor to ModelAndView.
DeleteContactController.java
1
|
package net.javabeat.articles.spring.mvc.contacts;
|
|
2
|
3
|
import javax.servlet.http.*;
|
|
4
|
import org.springframework.validation.BindException;
|
5
|
import org.springframework.web.servlet.ModelAndView;
|
|
6
|
import org.springframework.web.servlet.mvc.AbstractCommandController;
|
7
|
||
8
|
public class DeleteContactController extends AbstractCommandController{
|
9
|
|||
10
|
public DeleteContactController(){
|
||
11
|
setCommandClass(Contact.class);
|
|
12
|
}
|
13
|
||
14
|
public ModelAndView
handle(HttpServletRequest request,
|
15
|
HttpServletResponse
response, Object command, BindException errors)
|
|
16
|
throws Exception {
|
17
|
||
18
|
Contact
contact = (Contact)command;
|
19
|
ContactService.deleteContact(contact.getFirstName());
|
|
20
|
return new ModelAndView('DeletedContact');
|
21
|
||
22
|
}
|
23
|
}
|
Here
is the listing for ListContactsController.java.
ListContactsController.java
ListContactsController.java
1
|
package net.javabeat.articles.spring.mvc.contacts;
|
|
2
|
3
|
import java.util.List;
|
|
4
|
import javax.servlet.http.*;
|
5
|
import org.springframework.web.servlet.ModelAndView;
|
|
6
|
import org.springframework.web.servlet.mvc.AbstractController;
|
7
|
||
8
|
public class ListContactsController extends AbstractController{
|
9
|
|||
10
|
public ListContactsController() {
|
||
11
|
}
|
|
12
|
13
|
public ModelAndView
handleRequestInternal(HttpServletRequest request,
|
|
14
|
HttpServletResponse
response) throws Exception{
|
15
|
||
16
|
List
allContacts = ContactService.listContacts();
|
17
|
return new ModelAndView('ListContacts', 'allContacts', allContacts);
|
|
18
|
19
|
}
|
|
20
|
}
|
21
|
10) Conclusion
The
Article provided a basic Introduction over the core concepts in Spring MVC for the Web Tier.
Since the Spring Web Tier is built on top of the Spring Core Layer all the
functionalities like Bean Lifecycle Management, Dependency Injection etc. will be
automatically available to the Bean Components. Starting off with the
Interactions that will take place when a Client Request for a Resource, it
pointed out the various micro-level activities that take place in that Work
flow. Then the Core Components of Spring like Dispatcher Servlet, Controllers, Model/View,Handler Mappings, Handler Adapters and View Resolvers are also discussed
briefly. Finally the article ended up with the Simple Contact Application that
demonstrated the usage of the various types of Controllers.
- See more at: http://www.javabeat.net/introduction-to-spring-mvc-web-framework-web-tier/#sthash.SCaW3NKp.dpuf
No comments:
Post a Comment