org.springframework.web.servlet.mvc.multiaction

## Class MultiActionController

- java.lang.Object
- - org.springframework.context.support.ApplicationObjectSupport
  - - org.springframework.web.context.support.WebApplicationObjectSupport
    - - org.springframework.web.servlet.support.WebContentGenerator
      - - org.springframework.web.servlet.mvc.AbstractController
        - - org.springframework.web.servlet.mvc.multiaction.MultiActionController

- All Implemented Interfaces:
    Aware, ApplicationContextAware, ServletContextAware, 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

      public (ModelAndView | Map | String | void) actionName(HttpServletRequest request, HttpServletResponse response, [,HttpSession] [,AnyObject]);

  A Map return value indicates a model that is supposed to be passed to a default view (determined through a `RequestToViewNameTranslator`). A String return value indicates the name of a view to be rendered without a specific model.

  May take a third parameter (of type `HttpSession`) in which an existing session will be required, or a third parameter of an arbitrary class that gets treated as the command (that is, 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.

  When returning just a `Map` instance view name translation will be used to generate the view name. The configured `RequestToViewNameTranslator` will be used to determine the view name.

  When returning `void` a return value of `null` is assumed meaning that the handler method is responsible for writing the response directly to the supplied `HttpServletResponse`.

  This model allows for rapid coding, but loses the advantage of compile-time checking. It is similar to a Struts `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:

      public 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 `xxxLastModified` method for handlers, of signature:

      public 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 all handler methods need to be public and that method overloading is not allowed.

  See also the description of the workflow performed by `the superclass` (in that section of the class level Javadoc entitled 'workflow').

  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, Rob Harrop, Sam Brannen
  See Also:
    `MethodNameResolver`, `InternalPathMethodNameResolver`, `PropertiesMethodNameResolver`, `ParameterMethodNameResolver`, `LastModified.getLastModified(javax.servlet.http.HttpServletRequest)`, `ServletRequestDataBinder`

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `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 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

      `METHOD_GET, METHOD_HEAD, METHOD_POST`

    - ### Fields inherited from class org.springframework.context.support.ApplicationObjectSupport

      `logger`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `MultiActionController()` Constructor for `MultiActionController` that looks for handler methods in the present subclass.
    `MultiActionController(Object delegate)` Constructor for `MultiActionController` that looks for handler methods in delegate, rather than a subclass of this class.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected void` | `bind(HttpServletRequest request, Object command)` Bind request parameters onto the given command bean
    `protected ServletRequestDataBinder` | `createBinder(HttpServletRequest 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.
    `WebBindingInitializer` | `getWebBindingInitializer()` Return the WebBindingInitializer (if any) which will apply pre-configured configuration to every DataBinder that this controller uses.
    `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(HttpServletRequest 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; the default is `this`, assuming that handler methods have been added by a subclass.
    `void` | `setMethodNameResolver(MethodNameResolver methodNameResolver)` Set the method name resolver that this class should use.
    `void` | `setValidators(Validator[] validators)` Set the `Validators` for this controller.
    `void` | `setWebBindingInitializer(WebBindingInitializer webBindingInitializer)` Specify a WebBindingInitializer which will apply pre-configured configuration to every DataBinder that this controller uses.

    - ### 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, isAlwaysMustRevalidate, isRequireSession, isUseCacheControlHeader, isUseCacheControlNoStore, isUseExpiresHeader, preventCaching, setAlwaysMustRevalidate, setCacheSeconds, setRequireSession, setSupportedMethods, setUseCacheControlHeader, setUseCacheControlNoStore, setUseExpiresHeader`

    - ### Methods inherited from class org.springframework.web.context.support.WebApplicationObjectSupport

      `getServletContext, getTempDir, getWebApplicationContext, initApplicationContext, initServletContext, isContextRequired, setServletContext`

    - ### 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:
        `pageNotFoundLogger`, Constant Field Values

    - #### pageNotFoundLogger

          protected static final Log pageNotFoundLogger

      Additional logger to use when no mapped handler is found for a request.
      See Also:
        `PAGE_NOT_FOUND_LOG_CATEGORY`

  - ### Constructor Detail

    - #### MultiActionController

          public MultiActionController()

      Constructor for `MultiActionController` that looks for handler methods in the present subclass.

    - #### MultiActionController

          public MultiActionController(Object delegate)

      Constructor for `MultiActionController` that looks for handler methods in delegate, rather than a subclass of this class.
      Parameters:
        `delegate` - handler object. This does not need to implement any particular interface, as everything is done using reflection.

  - ### Method Detail

    - #### setDelegate

          public final void setDelegate(Object delegate)

      Set the delegate used by this class; the default is `this`, assuming that handler methods have been added by a subclass.

      This method does not get invoked once the class is configured.

      Parameters:
        `delegate` - an object containing handler methods
      Throws:
        `IllegalStateException` - if no handler methods are found

    - #### 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 `Validators` must support the specified command class.

    - #### getValidators

          public final Validator[] getValidators()

      Return the Validators for this controller.

    - #### setWebBindingInitializer

          public final void setWebBindingInitializer(WebBindingInitializer webBindingInitializer)

      Specify a WebBindingInitializer which will apply pre-configured configuration to every DataBinder that this controller uses.

      Allows for factoring out the entire binder configuration to separate objects, as an alternative to `initBinder(javax.servlet.http.HttpServletRequest, org.springframework.web.bind.ServletRequestDataBinder)`.

    - #### getWebBindingInitializer

          public final WebBindingInitializer getWebBindingInitializer()

      Return the WebBindingInitializer (if any) which will apply pre-configured configuration to every DataBinder that this controller uses.

    - #### getLastModified

          public long getLastModified(HttpServletRequest request)

      Try to find an XXXXLastModified method, where XXXX is the name of a handler. Return -1 if there's no such handler, indicating that content must be updated.
      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(HttpServletRequest 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(HttpServletRequest 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.

      The default implementation creates a standard ServletRequestDataBinder, 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.http.HttpServletRequest, java.lang.Object)`, `initBinder(javax.servlet.http.HttpServletRequest, 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(HttpServletRequest 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.

      The 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.http.HttpServletRequest, 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`