今天说说SpringMVC工作流程以及一些SpringMVC的配置情况:
一、SpringMVC流程图
二、Spring工作流程描述
接下来根据上面的流程图来说说Spring的工作流程:
1)用户向服务器发送请求,请求被SpringMVC
前端控制器DispatcherServlet
捕获。
2)DispatcherServlet
对请求URL进行解析,得到请求资源标识符(URI),判断请求URI对应的映射:
① 不存在,就再判断是否配置了mvc:default-servlet-handler:
如果没有配置,则控制器报映射查找不到,客户端展示404错误。
如果有配置,则执行目标资源(一般为静态资源,如:JS,CSS,HTML)。
② 存在就执行以下流程。
3)根据该URI,调用HandlerMapping
获得该Handler配置的所有相关的对象(包括Handler
对象以及Handler
对象对应的拦截器),最后以HandlerExecutionChain
对象的形式返回。
4)DispatcherServlet
根据获得的Handler,选择一个合适的HandlerAdapter
。
5)如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)
方法。
6)提取Request
中的数据模型,填充Handler
入参,开始执行Handler(controller)
方法,处理请求。在填充Handler
的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
① HttpMessageConveter
:将请求消息(如json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。
② 数据转换:对请求消息进行数据转换。如String转换为Integer。
③ 数据根式化:对请求信息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。
④ 数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
7)Handler
执行完成后,向DispatcherServlet
返回一个ModelAndView
对象。
8)此时将开始执行拦截器的postHandle(...)
方法【逆向】。
9)根据返回的ModelAndView
(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver
进行异常处理)选择一个适合的ViewResolver
(必须是已经注册到Spring容器中的ViewResolver
)返回给DispatcherServlet
,根据Model
和View
,来渲染视图。
10)在返回给客户端时需要执行拦截器的AfterCompletion
方法【逆向】。
11)将渲染结果返回给客户端。
三、源码解析
1)拷贝jar包
spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
commons-logging-1.1.3.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
2)配置文件web.xml
<!-- 配置springMVC核心控制器 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置DispatcherServlet的初始化参数:设置文件的路径和文件名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3)配置文件springmvc.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 设置扫描组件的包 -->
<context:component-scan base-package="com.atguigu.springmvc.handler"></context:component-scan>
<!-- 配置映射解析器,如何将控制器返回的结果字符串,转换为一个物理的视图 -->
<bean id="internalResourceViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
4)完成HelloWorld
① 页面链接
<a href="springmvc/helloWorld">helloWorld</a>
② 控制器方法
@RequestMapping(value="/helloWorld",method=RequestMethod.GET)
public String helloWorld() {
System.out.println("hello wrold");
return "success";
}
③ 成功页面
<h2>success</h2>
四、Debug
1)正常流程,运行正常。
2)没有配置<mvc:default-servlet-handler/>
,测试,直接报404。
http://localhost:8080/springmvc01/springmvc/views/test.html
十二月 19, 2020 11:25:59 上午 org.springframework.web.servlet.DispatcherServlet noHandlerFound
警告: No mapping found for HTTP request with URI [/springmvc01/springmvc/views/test.html] in DispatcherServlet with name ‘springDispatcherServlet’
3) 配置<mvc:default-servlet-handler/>
,测试,会去查找目标资源
4) 测试,依然发生错误,这时,需要配置:<mvc:annotation-driven/>
,否则,映射解析不好使。
5)HandlerExecutionChain
:mappedHandler
:包含了拦截器和处理器方法;
6) 没有配置<mvc:default-servlet-handler/>
,<mvc:annotation-driven/>
,发送一个不存在资源的请求路径,mappedHandler为null。
http://localhost:8080/springmvc01/springmvc/helloworld1
4) 配置<mvc:default-servlet-handler/>
,<mvc:annotation-driven/>
,发送一个不存在资源的请求路径:
http://localhost:8080/springmvc01/springmvc/helloworld1
mappedHandler
不为null,原因是当循环simpleUrlHandlerMapping
时,当做静态资源处理,如下图:
五、断点执行
关于SringMVC的工作流程就先说到这里,有什么问题及时交流。