今天講解一下在Springmvc中的HandlerAdaptor執行流程,明白這個過程,你就能畫出下面的圖:java
接下來咱們就來看看具體的實現過程吧。web
1.0在DispatcherServlet中找到getHandlerAdapter()方法spring
2.0進入getHandlerAdapter()具體的方法實現內apache
3.0獲取ModelAndView:api
4.0真正的執行者:瀏覽器
簡單地瞭解一下,仍是用具體的代碼來增強印象吧。架構
先把項目的架構搭建完成,依賴節點導入,進行下面的操做。mvc
MAVEN所需的依賴節點:app
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!--spring web jar 包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!--springmvc jar 包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!--spring-ormjar 包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <!--servlet api包--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-spec</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.1</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build>
web.xml的配置:jsp
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Archetype Created Web Application</display-name> <!--中央調度器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContextfirst.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
示例一:實現簡單的訪問
準備名稱爲FirstController的類
public class FirstController implements Controller{ /*第一個示例實現Controller接口*/ public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } }
編寫applicationfirst.xml:
<!--第一種方式實現--> <!--處理器--> <bean id="firstController" class="cn.happy.controller.FirstController"></bean> <!--處理器映射器--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello">firstController</prop> </props> </property> </bean> <!--視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean>
效果圖:
實例二:(註解方式)
@org.springframework.stereotype.Controller public class FirstController { /*第二個示例註解方式*/ @RequestMapping("1") public String index(){ return "index"; } @RequestMapping("2") public String index2(){ return "index2"; } }
applicationfirst.xml中的配置:
<!--第二種方式實現-註解--> <!--配置包掃描器--> <context:component-scan base-package="cn.happy.controller"></context:component-scan> <!--視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean>
如今項目中註解式開發仍是不錯的,簡單,簡潔。
效果圖:
示例三:(根據不用訪問名稱來實現訪問同一頁面)
public class FirstController extends AbstractController{ /*不一樣的訪問名稱訪問同一個方法*/ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } }
applicationfirst.xml中的配置:
<!--第三種實現方式 不一樣的訪問名稱AbstractResolver--> <!--處理器--> <bean id="firstController" class="cn.happy.controller.FirstController"> </bean> <!--視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--處理器映射器--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/h1">firstController</prop> <prop key="/h2">firstController</prop> </props> </property> </bean>
效果圖:
上圖是接口Controller的實現類,咱們能夠很清晰的看到Controller-------->AbstractController------->MultiActionController,還有一些其餘的子類,在這裏咱們就不一一介紹了,就拿MultiActionController爲例。
上面的圈起來的兩個類,就是方法名稱解析所用到的。
先來第一種方式:PropertiesMethodNameResolver
public class FirstController extends MultiActionController{ /*繼承MultiActionController propertiesMethodNameResolver*/ public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } public ModelAndView doSecond(HttpServletRequest request, HttpServletResponse response){ ModelAndView av=new ModelAndView(); av.setViewName("index2"); return av; } }
applicationfirst.xml中的配置:
<!--第四種方式實現 第一種 MultiActionSesolver--> <!--處理器--> <bean id="firstController" class="cn.happy.controller.FirstController"> <!--關聯方法名稱解析器--> <property name="methodNameResolver" ref="propertiesMethodNameResolver"></property> </bean> <!--視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--處理器映射器--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/*">firstController</prop> </props> </property> </bean> <!--方法名稱解析器 PropertiesMethodNameResolver--> <bean id="propertiesMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver"> <property name="mappings"> <props> <prop key="/h1">doFirst</prop> <prop key="/h2">doSecond</prop> </props> </property> </bean>
效果圖:
另外一種方式:ParameterMethodNameResolver,先來一張圖看一下
當你不指定paramName的時候默認爲action
public class FirstController extends MultiActionController{ /*繼承MultiActionController parameterMethodNameResolver*/ public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } public ModelAndView doSecond(HttpServletRequest request, HttpServletResponse response){ ModelAndView av=new ModelAndView(); av.setViewName("index2"); return av; } }
applicationContextfirst.xml的配置:
<!--第四種方式實現 第二種 MultiActionSesolver--> <!--處理器--> <bean id="firstController" class="cn.happy.controller.FirstController"> <!--關聯方法名稱解析器--> <property name="methodNameResolver" ref="parameterMethodNameResolver"></property> </bean> <!--視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--處理器映射器--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/*">firstController</prop> </props> </property> </bean> <!--方法名稱解析器 PropertiesMethodNameResolver--> <bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="actionName"></property> </bean>
指定了方法名稱解析器的參數,效果圖以下:
當註釋掉以後,默認爲action,效果圖:
<!--方法名稱解析器 PropertiesMethodNameResolver--> <bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <!--<property name="paramName" value="actionName"></property>--> </bean>
最後再來一組,訪問外部資源和訪問內部資源
public class FirstController extends MultiActionController{ public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) { ModelAndView av=new ModelAndView(); av.setViewName("jd"); return av; } }
applicationContextfirst.xml的配置:
<!--外部資源方式--> <!--處理器--> <bean id="firstController" class="cn.happy.controller.FirstController"> <property name="methodNameResolver" ref="parameterMethodNameResolver"></property> </bean> <!--方法名稱解析器--> <bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> </bean> <!--處理器映射器--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/*">firstController</prop> </props> </property> </bean> <!--外部資源--> <bean id="jd" class="org.springframework.web.servlet.view.RedirectView"> <property name="url" value="http://www.jd.com"></property> </bean> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"></bean>
在瀏覽器地址欄中填寫如圖所示地址:
內部資源訪問:
只須要更改一處便可:
<!--外部資源--> <bean id="jd" class="org.springframework.web.servlet.view.JstlView"> <property name="url" value="index2.jsp"></property> </bean>
效果圖: