`

Spring HandlerMapping ,Handleradapter ,ViewResolver

阅读更多

HandlerMapping是用来找到url对应的处理handler对象(beans),而不是找到url对应的处理函数。Handleradapter则是用来匹配到handler的某个具体的处理函数上,然后调度执行这个函数。

ViewResolver:这个是用来解析视图,并返回资源到前端用到。

 

  1. import javax.servlet.http.HttpServletRequest;  
  2. import javax.servlet.http.HttpServletResponse;  
  3.   
  4. import org.springframework.web.servlet.ModelAndView;  
  5. import org.springframework.web.servlet.mvc.Controller;  
  6.   
  7. public class HomeAction implements Controller{  
  8.   
  9.     @Override  
  10.     public ModelAndView handleRequest(HttpServletRequest request,  
  11.             HttpServletResponse response) throws Exception {  
  12.         return new ModelAndView("hello");  
  13.     }  
  14. }  

 

 

下面就要说说原理了。 
用过python Django框架的都知道Django对于访问方式的配置就是,一个url路径和一个函数配对,你访问这个url,就会直接调用这个函数,简单明了。对于java的面向对象来说,就要分两步走。第一步首先要找到是哪个对象,即handler,本工程的handler则是HomeAction对象。第二步要找到访问的函数,即HomeAction的handleRequest方法。所以就出现了两个源码接口 HandlerMapping和HandlerAdapter,前者负责第一步,后者负责第二步。借用网上的SpringMVC架构图。 

HandlerMapping接口的实现(只举了我认识的几个) : 


  • BeanNameUrlHandlerMapping :通过对比url和bean的name找到对应的对象 
    SimpleUrlHandlerMapping :也是直接配置url和对应bean,比BeanNameUrlHandlerMapping功能更多 
    DefaultAnnotationHandlerMapping : 主要是针对注解配置@RequestMapping的,已过时 
    RequestMappingHandlerMapping :取代了上面一个 


HandlerAdapter 接口实现: 


  • HttpRequestHandlerAdapter : 要求handler实现HttpRequestHandler接口,该接口的方法为                                                             void handleRequest(HttpServletRequest request, HttpServletResponse response)也就是  handler必须有一个handleRequest方法 

    SimpleControllerHandlerAdapter:要求handler实现Controller接口,该接口的方法为ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response),也就是本工程采用的 

    AnnotationMethodHandlerAdapter :和上面的DefaultAnnotationHandlerMapping配对使用的,也已过时 

    RequestMappingHandlerAdapter : 和上面的RequestMappingHandlerMapping配对使用,针对@RequestMapping 


先简单的说下这个工程的流程,访问http://localhost:8080/index首先由DispatcherServlet进行转发,通过BeanNameUrlHandlerMapping(含有 /index->HomeAction的配置),找到了HomeAction,然后再拿HomeAction和每个adapter进行适配,由于HomeAction实现了Controller接口,所以最终会有SimpleControllerHandlerAdapter来完成对HomeAction的handleRequest方法的调度。然后就顺利的执行了我们想要的方法,后面的内容不在本节中说明。 

了解了大概流程,然后就需要看源代码了。 
首先就是SpringMVC的入口类,DispatcherServlet,它实现了Servlet接口,不再详细说DispatcherServlet的细节,不然又是一大堆的内容。每次请求都会调用它的doService->doDispatch,我们关注的重点就在doDispatch方法中。 

Java代码  收藏代码
  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  2.         HttpServletRequest processedRequest = request;  
  3.         HandlerExecutionChain mappedHandler = null;  
  4.         boolean multipartRequestParsed = false;  
  5.   
  6.         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);  
  7.   
  8.         try {  
  9.             ModelAndView mv = null;  
  10.             Exception dispatchException = null;  
  11.   
  12.             try {  
  13.                 processedRequest = checkMultipart(request);  
  14.                 multipartRequestParsed = (processedRequest != request);  
  15.                       //这个是重点,第一步由HandlerMapping找到对应的handler  
  16.                 // Determine handler for the current request.  
  17.                 mappedHandler = getHandler(processedRequest);  
  18.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  19.                     noHandlerFound(processedRequest, response);  
  20.                     return;  
  21.                 }  
  22.   
  23.                 // Determine handler adapter for the current request.  
  24.                        //这是第二步,找到合适的HandlerAdapter,然后由它来调度执行handler的方法  
  25.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  26.   
  27.                 // Process last-modified header, if supported by the handler.  
  28.                 String method = request.getMethod();  
  29.                 boolean isGet = "GET".equals(method);  
  30.                 if (isGet || "HEAD".equals(method)) {  
  31.                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
  32.                     if (logger.isDebugEnabled()) {  
  33.                         logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);  
  34.                     }  
  35.                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
  36.                         return;  
  37.                     }  
  38.                 }  
  39.   
  40.                 if (!mappedHandler.applyPreHandle(processedRequest, response)) {  
  41.                     return;  
  42.                 }  
  43.   
  44.                 try {  
  45.                     // Actually invoke the handler.  
  46.                     mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  47.                 }  
  48.                 finally {  
  49.                     if (asyncManager.isConcurrentHandlingStarted()) {  
  50.                         return;  
  51.                     }  
  52.                 }  
  53.   
  54.                 applyDefaultViewName(request, mv);  
  55.                 mappedHandler.applyPostHandle(processedRequest, response, mv);  
  56.             }  
  57.             catch (Exception ex) {  
  58.                 dispatchException = ex;  
  59.             }  
  60.             processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);  
  61.         }  
  62.         catch (Exception ex) {  
  63.             triggerAfterCompletion(processedRequest, response, mappedHandler, ex);  
  64.         }  
  65.         catch (Error err) {  
  66.             triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);  
  67.         }  
  68.         finally {  
  69.             if (asyncManager.isConcurrentHandlingStarted()) {  
  70.                 // Instead of postHandle and afterCompletion  
  71.                 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);  
  72.                 return;  
  73.             }  
  74.             // Clean up any resources used by a multipart request.  
  75.             if (multipartRequestParsed) {  
  76.                 cleanupMultipart(processedRequest);  
  77.             }  
  78.         }  
  79.     }  


第一步详细查看: 

Java代码  收藏代码
  1. protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {  
  2.         for (HandlerMapping hm : this.handlerMappings) {  
  3.             if (logger.isTraceEnabled()) {  
  4.                 logger.trace(  
  5.                         "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");  
  6.             }  
  7.             HandlerExecutionChain handler = hm.getHandler(request);  
  8.             if (handler != null) {  
  9.                 return handler;  
  10.             }  
  11.         }  
  12.         return null;  
  13.     }  


可以看到就是通过遍历所有已注册的HandlerMapping来找到对应的handler,然后构建出一个HandlerExecutionChain,它包含了handler和HandlerMapping本身的一些拦截器,如下 

Java代码  收藏代码
  1. public class HandlerExecutionChain {  
  2.   
  3.     private final Object handler;  
  4.   
  5.     private HandlerInterceptor[] interceptors;  
  6.   
  7.     private List<HandlerInterceptor> interceptorList;  
  8.           
  9.         //其他代码省略  
  10. }  


其中HandlerMapping的getHandler实现: 

Java代码  收藏代码
  1. public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {  
  2.         Object handler = getHandlerInternal(request);  
  3.         if (handler == null) {  
  4.             handler = getDefaultHandler();  
  5.         }  
  6.         if (handler == null) {  
  7.             return null;  
  8.         }  
  9.         // Bean name or resolved handler?  
  10.         if (handler instanceof String) {  
  11.             String handlerName = (String) handler;  
  12.             handler = getApplicationContext().getBean(handlerName);  
  13.         }  
  14.         return getHandlerExecutionChain(handler, request);  
  15.     }  


这里的getHandlerInternal(request)是个抽象方法,由具体的HandlerMapping来实现,获取到的handler如果为空,则获取默认配置的handler,如果handler为String类型,则表示这个则会去Spring容器里面去找这样名字的bean。 
再看下BeanNameUrlHandlerMapping的getHandlerInternal(request)的具体实现(通过一系列的接口设计,之后再好好看看这个设计,到BeanNameUrlHandlerMapping这只用实现该方法中的一部分),如下
 

Java代码  收藏代码
  1. public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {  
  2.   
  3.     /** 
  4.      * Checks name and aliases of the given bean for URLs, starting with "/". 
  5.      */  
  6.     @Override  
  7.     protected String[] determineUrlsForHandler(String beanName) {  
  8.         List<String> urls = new ArrayList<String>();  
  9.         if (beanName.startsWith("/")) {  
  10.             urls.add(beanName);  
  11.         }  
  12.         String[] aliases = getApplicationContext().getAliases(beanName);  
  13.         for (String alias : aliases) {  
  14.             if (alias.startsWith("/")) {  
  15.                 urls.add(alias);  
  16.             }  
  17.         }  
  18.         return StringUtils.toStringArray(urls);  
  19.     }  
  20.   
  21. }  


这里面注释说,bean的name必须以/开头,它才处理,将信息存储在Map<String, Object> handlerMap中,对于本工程来说就是{'/index':HomeAction对象}。 
至此这里完成了第一步,下面开始第二步,即方法HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());的具体实现:
 

Java代码  收藏代码
  1. protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {  
  2.         for (HandlerAdapter ha : this.handlerAdapters) {  
  3.             if (logger.isTraceEnabled()) {  
  4.                 logger.trace("Testing handler adapter [" + ha + "]");  
  5.             }  
  6.             if (ha.supports(handler)) {  
  7.                 return ha;  
  8.             }  
  9.         }  
  10.         throw new ServletException("No adapter for handler [" + handler +  
  11.                 "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");  
  12.     }  


遍历所有的HandlerAdapter,判断他们是否支持这个handler。 
我们来看下HttpRequestHandlerAdapter的supports(handler)方法:
 

Java代码  收藏代码
  1. public class HttpRequestHandlerAdapter implements HandlerAdapter {  
  2.   
  3.     @Override  
  4.     public boolean supports(Object handler) {  
  5.           //就是判断handler是否实现了HttpRequestHandler接口  
  6.         return (handler instanceof HttpRequestHandler);  
  7.     }  
  8.   
  9.     @Override  
  10.     public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)  
  11.             throws Exception {  
  12.            //若handler实现了HttpRequestHandler接口,则调用该接口的方法,执行我们在该方法中写的业务逻辑  
  13.         ((HttpRequestHandler) handler).handleRequest(request, response);  
  14.         return null;  
  15.     }  
  16.   
  17.     @Override  
  18.     public long getLastModified(HttpServletRequest request, Object handler) {  
  19.         if (handler instanceof LastModified) {  
  20.             return ((LastModified) handler).getLastModified(request);  
  21.         }  
  22.         return -1L;  
  23.     }  
  24.   
  25. }  


同理SimpleControllerHandlerAdapter也是这样类似的逻辑 

Java代码  收藏代码
  1. public class SimpleControllerHandlerAdapter implements HandlerAdapter {  
  2.   
  3.     @Override  
  4.     public boolean supports(Object handler) {  
  5.         return (handler instanceof Controller);  
  6.     }  
  7.   
  8.     @Override  
  9.     public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)  
  10.             throws Exception {  
  11.   
  12.         return ((Controller) handler).handleRequest(request, response);  
  13.     }  
  14.   
  15.     @Override  
  16.     public long getLastModified(HttpServletRequest request, Object handler) {  
  17.         if (handler instanceof LastModified) {  
  18.             return ((LastModified) handler).getLastModified(request);  
  19.         }  
  20.         return -1L;  
  21.     }  
  22.   
  23. }  


剩余两个AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter就比较复杂,我也没看。 
按照本工程的配置,则SimpleControllerHandlerAdapter是支持HomeAction的,然后就会执行SimpleControllerHandlerAdapter的handle(processedRequest, response, mappedHandler.getHandler())方法。本质上就会调用HomeAction实现Controller接口的方法。至此就分析完了。 
了解过程了之后,然后就是最重要的也是经常配置出问题的地方。DispatcherServlet的handlerMappings和handlerAdapters的来源问题。 

DispatcherServlet初始化的时候,会调用一个方法如下: 

Java代码  收藏代码
  1. protected void initStrategies(ApplicationContext context) {  
  2.         initMultipartResolver(context);  
  3.         initLocaleResolver(context);  
  4.         initThemeResolver(context);  
  5. //初始化一些HandlerMapping  
  6.         initHandlerMappings(context);  
  7. //初始化一些HandlerAdapter  
  8.         initHandlerAdapters(context);  
  9.         initHandlerExceptionResolvers(context);  
  10.         initRequestToViewNameTranslator(context);  
  11.         initViewResolvers(context);  
  12.         initFlashMapManager(context);  
  13.     }  


这里可以看到,它会初始化一些HandlerMapping和HandlerAdapter,这两个方法非常重要,理解了这两个方法你就会知道,配置不对问题出在哪里,下面具体看下这两个方法: 

Java代码  收藏代码
  1. private void initHandlerMappings(ApplicationContext context) {  
  2.         this.handlerMappings = null;  
  3.   
  4.         if (this.detectAllHandlerMappings) {  
  5.             // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.  
  6.             Map<String, HandlerMapping> matchingBeans =  
  7.                     BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.classtruefalse);  
  8.             if (!matchingBeans.isEmpty()) {  
  9.                 this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());  
  10.                 // We keep HandlerMappings in sorted order.  
  11.                 OrderComparator.sort(this.handlerMappings);  
  12.             }  
  13.         }  
  14.         else {  
  15.             try {  
  16.                 HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);  
  17.                 this.handlerMappings = Collections.singletonList(hm);  
  18.             }  
  19.             catch (NoSuchBeanDefinitionException ex) {  
  20.                 // Ignore, we'll add a default HandlerMapping later.  
  21.             }  
  22.         }  
  23.   
  24.         // Ensure we have at least one HandlerMapping, by registering  
  25.         // a default HandlerMapping if no other mappings are found.  
  26.         if (this.handlerMappings == null) {  
  27.             this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);  
  28.             if (logger.isDebugEnabled()) {  
  29.                 logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");  
  30.             }  
  31.         }  
  32.     }  


detectAllHandlerMappings是DispatcherServlet的一个属性,你是可以在web.xml中配置的,默认是true,如果为true,则会去从本工程mvc-servlet.xml文件中去探测所有实现了HandlerMapping的bean,如果有,则加入DispatcherServlet的handlerMappings中。如果detectAllHandlerMappings为false,则直接去容器中找id="handlerMapping"且实现了HandlerMapping的bean.如果以上都没找到,则会去加载默认的HandlerMapping。 

Java代码  收藏代码
  1. /** Detect all HandlerMappings or just expect "handlerMapping" bean? */  
  2.     private boolean detectAllHandlerMappings = true;  


本工程由于没有配置HandlerMapping,所以它会去加载默认的,下面看看默认的配置是什么 

Java代码  收藏代码
  1. protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {  
  2.         String key = strategyInterface.getName();  
  3. //defaultStrategies存储了默认的配置  
  4.         String value = defaultStrategies.getProperty(key);  
  5.         if (value != null) {  
  6.             String[] classNames = StringUtils.commaDelimitedListToStringArray(value);  
  7.             List<T> strategies = new ArrayList<T>(classNames.length);  
  8.             for (String className : classNames) {  
  9.                 try {  
  10.                     Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());  
  11.                     Object strategy = createDefaultStrategy(context, clazz);  
  12.                     strategies.add((T) strategy);  
  13.                 }  
  14.                 catch (ClassNotFoundException ex) {  
  15.                     throw new BeanInitializationException(  
  16.                             "Could not find DispatcherServlet's default strategy class [" + className +  
  17.                                     "] for interface [" + key + "]", ex);  
  18.                 }  
  19.                 catch (LinkageError err) {  
  20.                     throw new BeanInitializationException(  
  21.                             "Error loading DispatcherServlet's default strategy class [" + className +  
  22.                                     "] for interface [" + key + "]: problem with class file or dependent class", err);  
  23.                 }  
  24.             }  
  25.             return strategies;  
  26.         }  
  27.         else {  
  28.             return new LinkedList<T>();  
  29.         }  
  30.     }  


继续看看defaultStrategies是如何初始化的: 

Java代码  收藏代码
  1. private static final Properties defaultStrategies;  
  2.   
  3.     static {  
  4.         // Load default strategy implementations from properties file.  
  5.         // This is currently strictly internal and not meant to be customized  
  6.         // by application developers.  
  7.         try {  
  8. //这里的DEFAULT_STRATEGIES_PATH就是DispatcherServlet.properties  
  9.             ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);  
  10.             defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);  
  11.         }  
  12.         catch (IOException ex) {  
  13.             throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());  
  14.         }  
  15.     }  


这里使用静态代码块来加载配置文件DispatcherServlet.properties,它所在位置就是和DispatcherServlet同一目录下面的,如下图所示: 


该默认的配置文件的内容如下: 

Java代码  收藏代码
  1. # Default implementation classes for DispatcherServlet's strategy interfaces.  
  2. # Used as fallback when no matching beans are found in the DispatcherServlet context.  
  3. # Not meant to be customized by application developers.  
  4.   
  5. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver  
  6.   
  7. org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver  
  8.   
  9. #这里就是默认的HandlerMapping的配置  
  10. org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\  
  11.     org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping  
  12. #这里就是默认的HandlerAdapter的配置  
  13. org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\  
  14.     org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\  
  15.     org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter  
  16.   
  17. org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\  
  18.     org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\  
  19.     org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver  
  20.   
  21. org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator  
  22.   
  23. org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver  
  24.   
  25. org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager  


也就是说,当你什么都没有配置时,默认会加载以上的配置。正是由于有了上述默认配置的BeanNameUrlHandlerMapping(它要求name必须是以/开头的),它才会存储我们在mvc-servlet.xml中配置的<bean name="/index" class="com.lg.mvc.HomeAction"></bean>,同样正是由于有了SimpleControllerHandlerAdapter(由于handler实现了Controller接口,所以它的support方法支持我们的handler),才会调度执行HomeAction的handleRequest方法。

分享到:
评论

相关推荐

    HandlerMapping HandlerAdapter View ViewResolver类图 矢量图

    HandlerMapping HandlerAdapter View ViewResolver类图 矢量图文件 https://blog.csdn.net/qq_39609993/article/details/105435850

    SpringMVC源码总结(一)HandlerMapping和HandlerAdapter入门

    NULL 博文链接:https://yihuawuye1.iteye.com/blog/2104547

    民宿网站管理系统java+spring.7z,架构是SSM

    Spring MVC 内置了 Requestmapping、HandlerMapping 和 ViewResolver 等组件,可以简化开发流程。MyBatis 作为持久层框架,负责处理数据库操作。 在安全性方面,该网站采用了 SSL 证书进行加密传输,并实现了用户...

    基于spring+java的教务管理系统.7z,SSM框架

    Spring MVC 内置了 Requestmapping、HandlerMapping 和 ViewResolver 等组件,可以简化开发流程。MyBatis 作为持久层框架,负责处理数据库操作。 在安全性方面,该教务管理系统采用了 SSL 证书进行加密传输,并实现...

    SpringMVC工作流程.vsdx

    该资源主要是SpringMVC工作流程,各个组件(DispatcherServlet、HandlerMapping、ViewResolver、Handler)的说明以及工作流程的文字说明等等。

    org.apache.cxf.spring.remoting.Jsr181HandlerMapping.jar

    org.apache.cxf.spring.remoting.Jsr181HandlerMapping.jar

    spring3mvc入门资料

    HandlerMapping接口 HandlerAdapter接口 Controller接口 HandlerInterceptor 接口 View接口 LocalResolver接口HandlerExceptionResolver接口 ModelAndView类 。

    Spring SpringMVC 简单整合

    Spring SpringMVC 简单整合(初学者参考) demo项目对应地址说明 :https://blog.csdn.net/tianyu00/article/details/89186404 SpringMVC流程 1、 用户发送请求至前端控制器DispatcherServlet。 2、 ...

    全面掌握Spring MVC:从基础到高级的实践指南

    处理器映射器(HandlerMapping)和处理器适配器(HandlerAdapter)是核心组件,负责找到和调用适当的处理器(Controller)。 Spring MVC的一个关键特性是它的灵活性,支持多种类型的控制器和视图技术。它还提供了...

    java spring mvc

    5)Spring MVC处理流程 a.... d.ModelAndView里包含了响应View和数据信息,主控制器调用ViewResolver视图解析器根据ModelAndView的内容寻找View组件,生成响应 e.主控制器将响应内容给客户浏览器输出

    Struts2+Spring3+MyBatis3完整实例

    org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,handlerMapping,handlerAdapter]; parent: org....

    springMVC技术概述

    springMVC相关技术配置使用注解的HandlerMapping和HandlerAdapter使用&lt;mvc:annotation-driver&gt; 不过springBoot已经省略了这些配置 配置使用注解的Handler和Service等等使用&lt;context:component-scan&gt; 不过springBoot...

    Spring MVC 学习笔记

    2、 DispatcherServlet把请求转交给HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象.(后面会学习到拦截器) 3、 ...

    Spring面试题

    2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller. 3.DispatcherServlet请请求提交到目标Controller 4.Controller进行业务逻辑处理后,会返回一个ModelAndView 5.Dispathcher查询一个...

    spring的web框架

    spring的web框架,详细的介绍有关框架的概述,DispatcherServlet、HandlerMapping、Controller、ModelAndView、ViewResolver、HandlerInterceptor的相关介绍

    看透springMvc源代码分析与实践

    8.2.2 创建Spring MVC的xml配置文件85 8.2.3 创建Controller和view86 8.3 关联spring源代码87 8.4 小结89 第9章 创建Spring MVC之器90 9.1 整体结构介绍90 9.2 HttpServletBean93 9.3 FrameworkServlet95 ...

    SPRING API 2.0.CHM

    HandlerMapping HandlerMapping HashMapCachingAdvisorChainFactory Hessian1SkeletonInvoker Hessian2SkeletonInvoker HessianClientInterceptor HessianProxyFactoryBean HessianServiceExporter ...

    Spring in Action(第二版 中文高清版).part2

    13.2.2 使用ControllerClassName HandlerMapping 13.2.3 使用元数据映射控制器 13.2.4 使用多映射处理器 13.3 用控制器处理请求 13.3.1 处理命令 13.3.2 处理表单提交 13.3.3 用向导处理复杂表单 13.3.4 ...

    Spring in Action(第二版 中文高清版).part1

    13.2.2 使用ControllerClassName HandlerMapping 13.2.3 使用元数据映射控制器 13.2.4 使用多映射处理器 13.3 用控制器处理请求 13.3.1 处理命令 13.3.2 处理表单提交 13.3.3 用向导处理复杂表单 13.3.4 ...

    spring1.0.zip

    闲来无事,手写Spring的mini版本 1.0, 目前只有几个核心功能, @Controller,@RequestMapping,@RequestParam,HandlerMapping,DispatchServlet等.但是从前端发起URL请求到后台可以处理结果并且返回, 实现了...

Global site tag (gtag.js) - Google Analytics