Base Controller interface, representing a component that receives HttpServletRequest
and HttpServletResponse like a HttpServlet but is able to participate in
an MVC workflow. Comparable to the notion of a Struts Action.
Any implementation of the Controller interface should be a
reusable, thread-safe class, capable of handling multiple
HTTP requests throughout the lifecycle of an application. To be able to
configure Controller in an easy way, Controllers are usually JavaBeans.
After the DispatcherServlet has received a request and has done its work
to resolve locales, themes and things a like, it tries to resolve a
Controller, using a HandlerMapping . When a Controller has been found, the
handleRequest
method will be invoked, which is responsible for handling the actual
request and - if applicable - returning an appropriate ModelAndView.
So actually, this method is the main entrypoint for the
DispatcherServlet
which delegates requests to controllers. This method - and also this interface -
should preferrably not be implemented by custom controllers directly, since
abstract controller also provided by this package already provide a lot of
functionality for typical use cases in web applications. A few examples of
those controllers:
AbstractController ,
AbstractCommandController ,
SimpleFormController .
So basically any direct implementation of the Controller interface
just handles HttpServletRequests and should return a ModelAndView, to be further
interpreted by the DispatcherServlet. Any additional functionality such as
optional validation, form handling, etc should be obtained through extending
one of the abstract controller classes mentioned above.
Notes on design and testing
The Controller interface is explicitly designed to operate on HttpServletRequest
and HttpServletResponse objects, just like an HttpServlet. It does not aim to
decouple from the Servlet API, in contrast to, for example, WebWork, JSF or Tapestry.
Instead, the full power of the Servlet API is available, allowing Controllers to be
general-purpose: not only to handle web user interface requests but also to process
remoting protocols or to generate reports on demand.
Controllers can easily be tested through passing in mock objects for servlet
request and response. For convenience, Spring ships with a set of Servlet API mocks
that are suitable for testing any kind of web components, but are particularly
suitable for testing Spring web controllers. In contrast to a Struts Action,
there is no need to mock the ActionServlet or any other infrastructure;
HttpServletRequest and HttpServletResponse are sufficient.
If Controllers need to be aware of specific environment references, they can
choose to implement specific awareness interfaces, just like any other bean in a
Spring (web) application context can do, for example:
Such environment references can easily be passed in testing environments,
through the corresponding setters defined in the respective awareness interfaces.
In general, it is recommended to keep the dependencies as minimal as possible:
for example, if all you need is resource loading, implement ResourceLoaderAware only.
Alternatively, derive from the WebApplicationObjectSupport base class, which gives
you all those references through convenient accessors - but requires an
ApplicationContext reference on initialization.
HttpServletbut is able to participate in an MVC workflow. Comparable to the notion of a StrutsAction.Any implementation of the Controller interface should be a reusable, thread-safe class, capable of handling multiple HTTP requests throughout the lifecycle of an application. To be able to configure Controller in an easy way, Controllers are usually JavaBeans.
Workflow
After the DispatcherServlet has received a request and has done its work to resolve locales, themes and things a like, it tries to resolve a Controller, using a HandlerMapping . When a Controller has been found, the handleRequest method will be invoked, which is responsible for handling the actual request and - if applicable - returning an appropriate ModelAndView. So actually, this method is the main entrypoint for the DispatcherServlet which delegates requests to controllers. This method - and also this interface - should preferrably not be implemented by custom controllers directly, since abstract controller also provided by this package already provide a lot of functionality for typical use cases in web applications. A few examples of those controllers: AbstractController , AbstractCommandController , SimpleFormController .
So basically any direct implementation of the Controller interface just handles HttpServletRequests and should return a ModelAndView, to be further interpreted by the DispatcherServlet. Any additional functionality such as optional validation, form handling, etc should be obtained through extending one of the abstract controller classes mentioned above.
Notes on design and testing
The Controller interface is explicitly designed to operate on HttpServletRequest and HttpServletResponse objects, just like an HttpServlet. It does not aim to decouple from the Servlet API, in contrast to, for example, WebWork, JSF or Tapestry. Instead, the full power of the Servlet API is available, allowing Controllers to be general-purpose: not only to handle web user interface requests but also to process remoting protocols or to generate reports on demand.
Controllers can easily be tested through passing in mock objects for servlet request and response. For convenience, Spring ships with a set of Servlet API mocks that are suitable for testing any kind of web components, but are particularly suitable for testing Spring web controllers. In contrast to a Struts Action, there is no need to mock the ActionServlet or any other infrastructure; HttpServletRequest and HttpServletResponse are sufficient.
If Controllers need to be aware of specific environment references, they can choose to implement specific awareness interfaces, just like any other bean in a Spring (web) application context can do, for example:
org.springframework.context.ApplicationContextAwareorg.springframework.context.ResourceLoaderAwareorg.springframework.web.context.ServletContextAwareSuch environment references can easily be passed in testing environments, through the corresponding setters defined in the respective awareness interfaces. In general, it is recommended to keep the dependencies as minimal as possible: for example, if all you need is resource loading, implement ResourceLoaderAware only. Alternatively, derive from the WebApplicationObjectSupport base class, which gives you all those references through convenient accessors - but requires an ApplicationContext reference on initialization.