spring mvc 源码(二) MultiActionController 处理流程(转)

spring mvc 提供了控制器的入口:接口Controller

 

Java代码  

  1. public interface Controller {  
  2.   
  3.     ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;  
  4.   
  5. }  

 

 

 

根据不同需要提供了不同实现的Controller,今天我们来说说最常用的MultiActionController,在一个controller里多个方法对应多个请求

 

1 首先来看一下MultiActionController的继承关系:

 

Java代码  

  1. public class MultiActionController extends AbstractController implements LastModified {}  

 MultiActionController继承了AbstractController

 

 

Java代码  

  1. public abstract class AbstractController extends WebContentGenerator implements Controller {}  

 AbstractController实现了Controller了接口

 

 

2 处理请求

   Controller处理请求应该调用handleRequest()方法,在MultiActionController类里没有handleRequest()方法的具体实现,所以会使用父类AbstractController里的handleRequest()方法,具体实现如下:

Java代码  

  1. public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)  
  2.         throws Exception {  
  3.   
  4.     // Delegate to WebContentGenerator for checking and preparing.  
  5.                //参数各方面的检查  
  6.     checkAndPrepare(request, response, this instanceof LastModified);  
  7.   
  8.     // Execute handleRequestInternal in synchronized block if required.  
  9.     if (this.synchronizeOnSession) {  
  10.         HttpSession session = request.getSession(false);  
  11.         if (session != null) {  
  12.             Object mutex = WebUtils.getSessionMutex(session);  
  13.             synchronized (mutex) {  
  14.                 return handleRequestInternal(request, response);  
  15.             }  
  16.         }  
  17.     }  
  18.   
  19.     return handleRequestInternal(request, response);  
  20. }  
  21.   
  22.        //子类去实现如何处理请求  
  23. protected abstract ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)  
  24.     throws Exception;  

 由上面代码可知,父类AbstractController里的handleRequest()方法不是一个完整的方法,具体处理请求的方法handleRequestInternal()由子类去实现,所以我们在MultiActionController去找handleRequestInternal()方法实现:

Java代码  

  1. protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)  
  2.         throws Exception {  
  3.     try {  
  4.                        //使用方法名解析器从请求中获取请求访问的方法名  
  5.         String methodName = this.methodNameResolver.getHandlerMethodName(request);  
  6.                        //调用具体的方法  
  7.         return invokeNamedMethod(methodName, request, response);  
  8.     }  
  9.     catch (NoSuchRequestHandlingMethodException ex) {  
  10.         return handleNoSuchRequestHandlingMethod(ex, request, response);  
  11.     }  
  12. }  

 上面方法的逻辑:使用methodNameResolver找到请求对应的方法名,然后调用方法,调用方法的具体实现为:

Java代码  

  1. protected final ModelAndView invokeNamedMethod(  
  2.         String methodName, HttpServletRequest request, HttpServletResponse response) throws Exception {  
  3.   
  4.                //根据具体的方法名获取到具体的方法  
  5.     Method method = this.handlerMethodMap.get(methodName);  
  6.     if (method == null) {  
  7.         throw new NoSuchRequestHandlingMethodException(methodName, getClass());  
  8.     }  
  9.   
  10.                //根据方法参数个数和类型,获取方法具体需要的参数request, response, 或者session 调用处理请求的方法  
  11.     try {  
  12.         Class[] paramTypes = method.getParameterTypes();  
  13.         List<Object> params = new ArrayList<Object>(4);  
  14.         params.add(request);  
  15.         params.add(response);  
  16.   
  17.         if (paramTypes.length >= 3 && paramTypes[2].equals(HttpSession.class)) {  
  18.             HttpSession session = request.getSession(false);  
  19.             if (session == null) {  
  20.                 throw new HttpSessionRequiredException(  
  21.                         “Pre-existing session required for handler method ‘” + methodName + “‘”);  
  22.             }  
  23.             params.add(session);  
  24.         }  
  25.   
  26.         // If last parameter isn’t of HttpSession type, it’s a command.  
  27.         if (paramTypes.length >= 3 &&  
  28.                 !paramTypes[paramTypes.length – 1].equals(HttpSession.class)) {  
  29.             Object command = newCommandObject(paramTypes[paramTypes.length – 1]);  
  30.             params.add(command);  
  31.             bind(request, command);  
  32.         }  
  33.   
  34.                        //调用具体的方法  
  35.         Object returnValue = method.invoke(this.delegate, params.toArray(new Object[params.size()]));  
  36.         return massageReturnValueIfNecessary(returnValue);  
  37.     }  
  38.     catch (InvocationTargetException ex) {  
  39.         // The handler method threw an exception.  
  40.         return handleException(request, response, ex.getTargetException());  
  41.     }  
  42.     catch (Exception ex) {  
  43.         // The binding process threw an exception.  
  44.         return handleException(request, response, ex);  
  45.     }  
  46. }  

 就是通过如上这个过程spring mvc 解析请求,找到对应的处理请求的方法,然后传入参数调用对应方法,完成整个请求的处理;有的controller只能处理一个请求,MultiActionController可以实现多个,就是因为handleRequestInternal()具体实现不同导致的。我们要实现自己的controller的时候,只要继承MultiActionController然后实现方法即可!

    原文作者:Spring MVC
    原文地址: https://blog.csdn.net/s21769775/article/details/45172249
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞