(DispatcherServlet在Spring当中充当一个前端控制器的角色,它的核心功能是分发请求。请求会被分发给对应处理的Java类,Spring MVC中称为Handle。)

①   用户把请求发送给DispatcherServlet服务器。

②   DispatcherServlet对请求的URL(统一资源定位符)进行解析,得到URI(请求资源标识符)。然后根据该URI,调用HandlerMapping获取该Handler配置的所有相关的对象,包括Handler对象以及Handler对象对应的拦截器,这些对象会被封装到一个HandlerExecutionChain对象当中返回。

③   DisptcharServlet会根据获得的Handler选择一个合适的HandlerAdapter。HandlerAdapter会被用于处理多种Handler,调用Handler实际处理请求的方法。

④   提取请求中的模型数据,开始执行Handler(Controller类)。在填充Handler的入参过程中,根据配置,Spring可以做消息转换、数据转换、数据格式化、数据验证的工作。

⑤   Handler执行完成后,想DispatcherServlet发送一个ModelAndView对象,ModelAndView对象中应该包含视图名或视图名和模型。

⑥   根据返回的ModelAndView对象,选择一个合适的ViewResolver(视图解析器)返回给DispatcherServlet。

⑦   ViewResolver结合Model和View来渲染视图。

⑧   将视图渲染结果返回给客户端。

我们可以看到,DispatcherServlet在这个执行过程中是一位大哥的角色,为森么它会坐稳大佬的位置呢?我们可以看它的源码:

         protected void initStrategies(ApplicationContext context) {

                   initMultipartResolver(context);  //初始化上传文件解析器

                   initLocaleResolver(context);  //初始化本地解析器

                   initThemeResolver(context);  // 初始化主体解析器

                   initHandlerMappings(context);  //初始化处理器映射器,将请求映射到处理器

                   initHandlerAdapters(context);  //初始化处理器适配器

                   initHandlerExceptionResolvers(context);  //初始化处理异常解析器,如果执行过程中遇到异常将交给HandlerExceptionResolver来解析

                   initRequestToViewNameTranslator(context);  //初始化请求到视图名称解析器

                   initViewResolvers(context);  //初始化视图解析器,通过ViewResolver解析逻辑视图名到具体视图实现

                   initFlashMapManager(context);  //初始化flash映射管理器

         }

接下来我们来看一下,整个流程的实现是怎么样的。

代码实现:

①   引入spirng-framework的相关包和commons-logging包(WEB-INF/lib)。

②   在WEB-INF下的web.xml中进行配置(WEB-INF/web.xml):

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

id="WebApp_ID" version="3.1">

<!-- 定义Spring MVC的前端控制器 -->

         <servlet>

                   <!-- 配置前端控制器 -->

                   <!-- DispatcherServlet在Spring当中充当一个前端控制器的角色,它的核心功能是分发请求。

                            请求会被分发给对应处理的Java类,Spring MVC中称为Handle

                    -->

           <!—配置一个名为springmvc的DispatcherServlet服务器 -->

                   <servlet-name>springmvc</servlet-name>

                   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

                   <init-param>

                            <!-- 定位spring mvc的配置文件 -->

                            <param-name>contextConfigLocation</param-name>

                            <param-value>/WEB-INF/springmvc-config.xml</param-value>

                   </init-param>

                   <load-on-startup>1</load-on-startup>

         </servlet>

         <!-- 让Spring mvc的前端控制器拦截所有请求 -->

         <servlet-mapping>

                   <servlet-name>springmvc</servlet-name>

                   <url-pattern>/</url-pattern>

         </servlet-mapping>

</web-app>

③      编写SpringMVC的配置文件,在WEB-INF下的springmvc-config.xml。(WEB-INF/springmvc-config.xml)


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.2.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.2.xsd"> 

<!-- 配置handler,映射"/hello",或者可以直接在Controller类注解 -->

<bean name="/hello" class="org.fkit.controller.HelloController"/>

<!-- spring可以自动去扫描base-pack下面的包或者子包下面的Java文件

         ,如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean

-->

<context:component-scan base-package="org.fkit.controller" />

<!-- 处理映射器将bean的name作为url进行查找,需要在配置Handle时指定name(即url) -->

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

<!-- SimpleControllerHandlerAdapter是一个处理器适配器,所有处理适配器都要实现HandlerAdapter接口 -->

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

<!-- 视图解析器 -->

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>

</beans>

④    Controller的实现,用于处理请求(org.fkit.controller.HelloController)。

package org.fkit.controller;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller{

         private static final Log logger = LogFactory.getLog(HelloController.class);

         public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

                   logger.info("handleRequest 被调用");

                   //创建准备返回的ModelAndView对象,该对象通常包含了返回视图名、模型的名称以及模型对象

                   ModelAndView mv = new ModelAndView();

                   //添加模型数据,可以是任意的POJO对象

                   mv.addObject("message","HelloWorld");

                   //设置逻辑视图名,视图解析器会根据该名字解析到具体的试图页面

mv.setViewName("/WEB-INF/content/welcome.jsp");
//返回ModelAndView对象 return mv; } }

⑤   编写视图页面,用于显示已经处理好的View和Model的视图渲染(WEB-INF/content/welcome.jsp)。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

</head>

<body>

         ${requestScope.message }

</body>

</html>

最新文章

  1. 初识The Battle of Polytopia
  2. .Net程序员之Python基础教程学习----字符串的使用 [Second Day]
  3. jquery $.each 和for怎么跳出循环终止本次循环
  4. MyBatis知多少(26)MyBatis和Hibernate区别
  5. iOS设计模式反思之单例模式的进化
  6. 关于javascript 里面类型的判断
  7. 小项目--反eclass
  8. c++多线程崩溃错误1
  9. jchat:linux聊天程序3:服务器
  10. 【一步一步】Spring 源码环境搭建
  11. 关于建立MySQL数据库,中文出现乱码问题
  12. Drupal 通过API动态的加入样式文件
  13. springboot获取URL请求参数的多种方式
  14. Mybatis Plus启动注入 SQL 原理分析
  15. 20162328蔡文琛 Bag类
  16. spring核心及常用技术
  17. CoreAnimation confusion: CATransaction vs CATransition vs CAAnimationGroup?
  18. hdu 1269 迷宫城堡(Targin算法)
  19. 有道单词导入 有道单词 生词本 批量导入 添加 有道单词XML 背单词
  20. 简单概括下浏览器事件模型,如何获得资源dom节点

热门文章

  1. 线段树优化建图(cf787d, 2019Wannafly Winter Camp Day7 Div1 E)
  2. java定时器Timer的使用
  3. Uploadify API在项目上的应用
  4. ASP.NET中MessageBox的实现
  5. E20190114-hm
  6. java 大数详细讲解
  7. Beatcoder#39+#41+#42
  8. C#中的yield return
  9. js对数组处理(数组里边相同元素提取成map)
  10. 关于idea中使用lamb表达式报错:ambda expressions are not supported at this language level