org.springframework.web.servlet.mvc.multiaction
Class MultiActionController

java.lang.Object
  extended by org.springframework.context.support.ApplicationObjectSupport
      extended by org.springframework.web.context.support.WebApplicationObjectSupport
          extended by org.springframework.web.servlet.support.WebContentGenerator
              extended by org.springframework.web.servlet.mvc.AbstractController
                  extended by org.springframework.web.servlet.mvc.multiaction.MultiActionController
All Implemented Interfaces:
ApplicationContextAware, Controller, LastModified

public class MultiActionController
extends AbstractController
implements LastModified

Controller implementation that allows multiple request types to be handled by the same class. Subclasses of this class can handle several different types of request with methods of the form

 ModelAndView actionName(HttpServletRequest request, HttpServletResponse response);
May take a third parameter HttpSession in which an existing session will be required, or a third parameter of an arbitrary class that gets treated as command (i.e. an instance of the class gets created, and request parameters get bound to it)

These methods can throw any kind of exception, but should only let propagate those that they consider fatal, or which their class or superclass is prepared to catch by implementing an exception handler.

This model allows for rapid coding, but loses the advantage of compile-time checking. It is similar to a Struts 1.1 DispatchAction, but more sophisticated. Also supports delegation to another object.

An implementation of the MethodNameResolver interface defined in this package should return a method name for a given request, based on any aspect of the request, such as its URL or an "action" parameter. The actual strategy can be configured via the "methodNameResolver" bean property, for each MultiActionController.

The default MethodNameResolver is InternalPathMethodNameResolver; further included strategies are PropertiesMethodNameResolver and ParameterMethodNameResolver.

Subclasses can implement custom exception handler methods with names such as:

 ModelAndView anyMeaningfulName(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception);
The third parameter can be any subclass or Exception or RuntimeException.

There can also be an optional lastModified method for handlers, of signature:

 long anyMeaningfulNameLastModified(HttpServletRequest request)
If such a method is present, it will be invoked. Default return from getLastModified is -1, meaning that the content must always be regenerated.

Note that method overloading isn't allowed.

See also description of workflow performed by superclasses here.

Note: For maximum data binding flexibility, consider direct usage of a ServletRequestDataBinder in your controller method, instead of relying on a declared command argument. This allows for full control over the entire binder setup and usage, including the invocation of Validators and the subsequent evaluation of binding/validation errors.

Author:
Rod Johnson, Juergen Hoeller, Colin Sampaleanu
See Also:
MethodNameResolver, InternalPathMethodNameResolver, PropertiesMethodNameResolver, ParameterMethodNameResolver, LastModified.getLastModified(javax.servlet.http.HttpServletRequest), ServletRequestDataBinder

Field Summary
static String DEFAULT_COMMAND_NAME
          Default command name used for binding command objects: "command"
static String LAST_MODIFIED_METHOD_SUFFIX
          Suffix for last-modified methods
static String PAGE_NOT_FOUND_LOG_CATEGORY
          Log category to use when no mapped handler is found for a request
protected static org.apache.commons.logging.Log pageNotFoundLogger
          Additional logger to use when no mapped handler is found for a request
 
Fields inherited from class org.springframework.web.servlet.support.WebContentGenerator
HEADER_CACHE_CONTROL, HEADER_EXPIRES, HEADER_PRAGMA, METHOD_GET, METHOD_HEAD, METHOD_POST
 
Fields inherited from class org.springframework.context.support.ApplicationObjectSupport
logger
 
Constructor Summary
MultiActionController()
          Constructor for MultiActionController that looks for handler methods in the present subclass.Caches methods for quick invocation later.
MultiActionController(Object delegate)
          Constructor for MultiActionController that looks for handler methods in delegate, rather than a subclass of this class.
 
Method Summary
protected  void bind(ServletRequest request, Object command)
          Bind request parameters onto the given command bean
protected  ServletRequestDataBinder createBinder(ServletRequest request, Object command)
          Create a new binder instance for the given command and request.
protected  String getCommandName(Object command)
          Return the command name to use for the given command object.
protected  Method getExceptionHandler(Throwable exception)
          Determine the exception handler method for the given exception.
 long getLastModified(HttpServletRequest request)
          Try to find an XXXXLastModified method, where XXXX is the name of a handler.
 MethodNameResolver getMethodNameResolver()
          Return the MethodNameResolver used by this class.
 Validator[] getValidators()
          Return the Validators for this controller.
protected  ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, HttpServletRequest request, HttpServletResponse response)
          Handle the case where no request handler method was found.
protected  ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
          Determine a handler method and invoke it.
protected  void initBinder(ServletRequest request, ServletRequestDataBinder binder)
          Initialize the given binder instance, for example with custom editors.
protected  ModelAndView invokeNamedMethod(String methodName, HttpServletRequest request, HttpServletResponse response)
          Invokes the named method.
protected  Object newCommandObject(Class clazz)
          Create a new command object of the given class.
 void setDelegate(Object delegate)
          Set the delegate used by this class.
 void setMethodNameResolver(MethodNameResolver methodNameResolver)
          Set the method name resolver that this class should use.
 void setValidators(Validator[] validators)
          Set the Validators for this controller.
 
Methods inherited from class org.springframework.web.servlet.mvc.AbstractController
handleRequest, isSynchronizeOnSession, setSynchronizeOnSession
 
Methods inherited from class org.springframework.web.servlet.support.WebContentGenerator
applyCacheSeconds, applyCacheSeconds, cacheForSeconds, cacheForSeconds, checkAndPrepare, checkAndPrepare, getCacheSeconds, getSupportedMethods, isRequireSession, isUseCacheControlHeader, isUseExpiresHeader, preventCaching, setCacheSeconds, setRequireSession, setSupportedMethods, setUseCacheControlHeader, setUseExpiresHeader
 
Methods inherited from class org.springframework.web.context.support.WebApplicationObjectSupport
getServletContext, getTempDir, getWebApplicationContext, isContextRequired
 
Methods inherited from class org.springframework.context.support.ApplicationObjectSupport
getApplicationContext, getMessageSourceAccessor, initApplicationContext, requiredContextClass, setApplicationContext
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

LAST_MODIFIED_METHOD_SUFFIX

public static final String LAST_MODIFIED_METHOD_SUFFIX
Suffix for last-modified methods

See Also:
Constant Field Values

DEFAULT_COMMAND_NAME

public static final String DEFAULT_COMMAND_NAME
Default command name used for binding command objects: "command"

See Also:
Constant Field Values

PAGE_NOT_FOUND_LOG_CATEGORY

public static final String PAGE_NOT_FOUND_LOG_CATEGORY
Log category to use when no mapped handler is found for a request

See Also:
Constant Field Values

pageNotFoundLogger

protected static final org.apache.commons.logging.Log pageNotFoundLogger
Additional logger to use when no mapped handler is found for a request

Constructor Detail

MultiActionController

public MultiActionController()
                      throws ApplicationContextException
Constructor for MultiActionController that looks for handler methods in the present subclass.Caches methods for quick invocation later. This class's use of reflection will impose little overhead at runtime.

Throws:
ApplicationContextException - if the class doesn't contain any action handler methods (and so could never handle any requests).

MultiActionController

public MultiActionController(Object delegate)
                      throws ApplicationContextException
Constructor for MultiActionController that looks for handler methods in delegate, rather than a subclass of this class. Caches methods.

Parameters:
delegate - handler class. This doesn't need to implement any particular interface, as everything is done using reflection.
Throws:
ApplicationContextException - if the class doesn't contain any handler methods
Method Detail

setMethodNameResolver

public final void setMethodNameResolver(MethodNameResolver methodNameResolver)
Set the method name resolver that this class should use. Allows parameterization of handler method mappings.


getMethodNameResolver

public final MethodNameResolver getMethodNameResolver()
Return the MethodNameResolver used by this class.


setValidators

public final void setValidators(Validator[] validators)
Set the Validators for this controller. The Validator must support the specified command class.


getValidators

public final Validator[] getValidators()
Return the Validators for this controller.


setDelegate

public final void setDelegate(Object delegate)
                       throws ApplicationContextException
Set the delegate used by this class. The default is this, assuming that handler methods have been added by a subclass. This method is rarely invoked once the class is configured.

Parameters:
delegate - class containing methods, which may be the present class, the handler methods being in a subclass
Throws:
ApplicationContextException - if there aren't any valid request handling methods in the subclass.

getLastModified

public long getLastModified(HttpServletRequest request)
Try to find an XXXXLastModified method, where XXXX is the name of a handler. Return -1, indicating that content must be updated, if there's no such handler.

Specified by:
getLastModified in interface LastModified
Parameters:
request - current HTTP request
Returns:
the time the underlying resource was last modified, or -1 meaning that the content must always be regenerated
See Also:
LastModified.getLastModified(HttpServletRequest)

handleRequestInternal

protected ModelAndView handleRequestInternal(HttpServletRequest request,
                                             HttpServletResponse response)
                                      throws Exception
Determine a handler method and invoke it.

Specified by:
handleRequestInternal in class AbstractController
Throws:
Exception
See Also:
MethodNameResolver.getHandlerMethodName(javax.servlet.http.HttpServletRequest), invokeNamedMethod(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse), handleNoSuchRequestHandlingMethod(org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)

handleNoSuchRequestHandlingMethod

protected ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex,
                                                         HttpServletRequest request,
                                                         HttpServletResponse response)
                                                  throws Exception
Handle the case where no request handler method was found.

The default implementation logs a warning and sends an HTTP 404 error. Alternatively, a fallback view could be chosen, or the NoSuchRequestHandlingMethodException could be rethrown as-is.

Parameters:
ex - the NoSuchRequestHandlingMethodException to be handled
request - current HTTP request
response - current HTTP response
Returns:
a ModelAndView to render, or null if handled directly
Throws:
Exception - an Exception that should be thrown as result of the servlet request

invokeNamedMethod

protected final ModelAndView invokeNamedMethod(String methodName,
                                               HttpServletRequest request,
                                               HttpServletResponse response)
                                        throws Exception
Invokes the named method.

Uses a custom exception handler if possible; otherwise, throw an unchecked exception; wrap a checked exception or Throwable.

Throws:
Exception

newCommandObject

protected Object newCommandObject(Class clazz)
                           throws Exception
Create a new command object of the given class.

This implementation uses BeanUtils.instantiateClass, so commands need to have public no-arg constructors. Subclasses can override this implementation if desired.

Throws:
Exception - if the command object could not be instantiated
See Also:
BeanUtils.instantiateClass(Class)

bind

protected void bind(ServletRequest request,
                    Object command)
             throws Exception
Bind request parameters onto the given command bean

Parameters:
request - request from which parameters will be bound
command - command object, that must be a JavaBean
Throws:
Exception - in case of invalid state or arguments

createBinder

protected ServletRequestDataBinder createBinder(ServletRequest request,
                                                Object command)
                                         throws Exception
Create a new binder instance for the given command and request.

Called by bind. Can be overridden to plug in custom ServletRequestDataBinder subclasses.

Default implementation creates a standard ServletRequestDataBinder, sets the specified MessageCodesResolver (if any), and invokes initBinder. Note that initBinder will not be invoked if you override this method!

Parameters:
request - current HTTP request
command - the command to bind onto
Returns:
the new binder instance
Throws:
Exception - in case of invalid state or arguments
See Also:
bind(javax.servlet.ServletRequest, java.lang.Object), initBinder(javax.servlet.ServletRequest, org.springframework.web.bind.ServletRequestDataBinder)

getCommandName

protected String getCommandName(Object command)
Return the command name to use for the given command object. Default is "command".

Parameters:
command - the command object
Returns:
the command name to use
See Also:
DEFAULT_COMMAND_NAME

initBinder

protected void initBinder(ServletRequest request,
                          ServletRequestDataBinder binder)
                   throws Exception
Initialize the given binder instance, for example with custom editors. Called by createBinder.

This method allows you to register custom editors for certain fields of your command class. For instance, you will be able to transform Date objects into a String pattern and back, in order to allow your JavaBeans to have Date properties and still be able to set and display them in an HTML interface.

Default implementation is empty.

Note: the command object is not directly passed to this method, but it's available via DataBinder.getTarget()

Parameters:
request - current HTTP request
binder - new binder instance
Throws:
Exception - in case of invalid state or arguments
See Also:
createBinder(javax.servlet.ServletRequest, java.lang.Object), DataBinder.registerCustomEditor(java.lang.Class, java.beans.PropertyEditor), CustomDateEditor

getExceptionHandler

protected Method getExceptionHandler(Throwable exception)
Determine the exception handler method for the given exception. Can return null if not found.

Parameters:
exception - the exception to handle
Returns:
a handler for the given exception type, or null


Copyright (c) 2002-2006 The Spring Framework Project.