类 MultiActionController
- java.lang.Object
-
- WebApplicationObjectSupport
-
- org.springframework.web.servlet.support.WebContentGenerator
-
- org.springframework.web.servlet.mvc.AbstractController
-
- org.springframework.web.servlet.mvc.multiaction.MultiActionController
-
-
所有已实现的接口:
- 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 formpublic (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 aRequestToViewNameTranslator
). 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 configuredRequestToViewNameTranslator
will be used to determine the view name.When returning
void
a return value ofnull
is assumed meaning that the handler method is responsible for writing the response directly to the suppliedHttpServletResponse
.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 eachMultiActionController
.The default
MethodNameResolver
isInternalPathMethodNameResolver
; further included strategies arePropertiesMethodNameResolver
andParameterMethodNameResolver
.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 orException
orRuntimeException
.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 fromgetLastModified
is -1, meaning that the content must always be regenerated.Note that all handler methods need to be public and that method overloading isnot 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 ofValidators
and the subsequent evaluation of binding/validation errors.-
另请参阅:
-
MethodNameResolver
,InternalPathMethodNameResolver
,PropertiesMethodNameResolver
,ParameterMethodNameResolver
,LastModified.getLastModified(HttpServletRequest)
,org.springframework.web.bind.ServletRequestDataBinder
//******* MultiActionController.java************** package org.springframework.web.servlet.mvc.multiaction; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; //导入servelt类 import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; //导入spring类 import org.springframework.beans.BeanUtils; import org.springframework.util.Assert; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; import org.springframework.web.HttpSessionRequiredException; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; import org.springframework.web.servlet.mvc.LastModified; import org.springframework.web.util.NestedServletException; /** 该类主要实现多动作控制 */ public class MultiActionController extends AbstractController implements LastModified { public static final String LAST_MODIFIED_METHOD_SUFFIX = "LastModified"; /** 定义绑定对象的名称为"command" */ public static final String DEFAULT_COMMAND_NAME = "command"; /** 当没有映射被找到时定义使用的类 */ public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web. servlet.PageNotFound"; /** 没有映射被找到时的日志类 */ protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_ FOUND_ LOG_CATEGORY); /** 根据传来的request解析方法 */ private MethodNameResolver methodNameResolver = new InternalPathMethodNameResolver(); /** command的验证信息 */ private Validator[] validators; /** 默认使用的多动作解析方法 */ private Object delegate; /** 存储所有的方法 */ private Map handlerMethodMap = new HashMap(); private Map lastModifiedMethodMap = new HashMap(); /** 定义所有的异常类 */ private Map exceptionHandlerMap = new HashMap(); /**构造函数*/ public MultiActionController() { thisthis.delegate = this; registerHandlerMethods(this.delegate); } /** 构造函数 */ public MultiActionController(Object delegate) { setDelegate(delegate); } /** 设定解析方法类 */ public final void setMethodNameResolver(MethodNameResolver methodNameResolver) { this.methodNameResolver = methodNameResolver; } /** 返回方法的解析类 */ public final MethodNameResolver getMethodNameResolver() { return this.methodNameResolver; } /** 设定验证信息 */ public final void setValidators(Validator[] validators) { this.validators = validators; } /** 返回验证信息 */ public final Validator[] getValidators() { return validators; } /** 设定委托类 */ public final void setDelegate(Object delegate) { Assert.notNull(delegate, "Delegate must not be null"); this.delegate = delegate; //注册方法 registerHandlerMethods(this.delegate); // 假如没有方法 if (this.handlerMethodMap.isEmpty()) { throw new IllegalStateException("No handler methods in class [" + this.delegate.getClass() + "]"); } } /** 注册所有的方法到委托类 */ private void registerHandlerMethods(Object delegate) { //清空所有的Map this.handlerMethodMap.clear(); this.lastModifiedMethodMap.clear(); this.exceptionHandlerMap.clear(); //获取所有的方法 Method[] methods = delegate.getClass().getMethods(); for (int i = 0; i < methods.length; i++) { //根据request查找要处理的方法 Method method = methods[i]; //判断是否为要处理的方法 if (isHandlerMethod(method)) { registerHandlerMethod(method); registerLastModifiedMethodIfExists(delegate, method); } } //找所有的异常处理方法 for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (isExceptionHandlerMethod(method)) { //注册一个异常处理方法 registerExceptionHandlerMethod(method); } } } /** 判断是否是要处理的方法 */ private boolean isHandlerMethod(Method method) { Class returnType = method.getReturnType(); //首先判断该方法的返回类型是否为ModelAndView if (ModelAndView.class.equals(returnType) || Map.class.equals(returnType) || void.class.equals(returnType)) { Class[] parameterTypes = method.getParameterTypes(); //查看该方法的参数是否大于两个,并且是ServletRequest和ServletResponse return (parameterTypes.length >= 2 && HttpServletRequest.class.equals(parameterTypes[0]) && HttpServletResponse.class.equals(parameterTypes[1]) && !("handleRequest".equals(method.getName()) && parameterTypes. length == 2)); } return false; } /** 判断是否为异常的处理方法 */ private boolean isExceptionHandlerMethod(Method method) { return (isHandlerMethod(method) && method.getParameterTypes().length == 3 && Throwable.class.isAssignableFrom(method.getParameterTypes()[2])); } /** 注册要处理的方法 */ private void registerHandlerMethod(Method method) { if (logger.isDebugEnabled()) { logger.debug("Found action method [" + method + "]"); } //存放在Map中 this.handlerMethodMap.put(method.getName(), method); } /** 注册LastModified方法 */ private void registerLastModifiedMethodIfExists(Object delegate, Method method) { //查找相应的LastModified方法. try { Method lastModifiedMethod = delegate.getClass().getMethod( method.getName() + LAST_MODIFIED_METHOD_SUFFIX, new Class[] {HttpServletRequest.class}); //存放在Map中 this.lastModifiedMethodMap.put(method.getName(), lastModifiedMethod); if (logger.isDebugEnabled()) { logger.debug("Found last modified method for action method [" + method + "]"); } } } } /** 注册一个异常方法 */ private void registerExceptionHandlerMethod(Method method) { this.exceptionHandlerMap.put(method.getParameterTypes()[2], method); if (logger.isDebugEnabled()) { logger.debug("Found exception handler method [" + method + "]"); } } /** 获取LastModified */ public long getLastModified(HttpServletRequest request) { try { //获取要处理的方法 String handlerMethodName = this.methodNameResolver.getHandlerMethodName(request); Method lastModifiedMethod = (Method) this.lastModifiedMethodMap.get (handlerMethodName); //假如lastModifiedMethod不为空 if (lastModifiedMethod != null) { try { //调用last-modified方法 Long wrappedLong = (Long) lastModifiedMethod.invoke (this. delegate, new Object[] { request }); return wrappedLong.longValue(); } catch (Exception ex) { logger.error("Failed to invoke last-modified method", ex); } } //假如有一个lastModified 方法在request中 } catch (NoSuchRequestHandlingMethodException ex) { } return -1L; }
-
转载自: http://www.boyunjian.com/javadoc/org.springframework/spring-webmvc/3.2.3.RELEASE/_/org/springframework/web/servlet/mvc/multiaction/MultiActionController.html