今天说说SpringMVC工作流程以及一些SpringMVC的配置情况:

一、SpringMVC流程图

springmvc 配置log4j 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,根据ModelView,来渲染视图。

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/>,否则,映射解析不好使。

springmvc 配置log4j springmvc 配置流程_核心控制器_02

5)HandlerExecutionChain:mappedHandler:包含了拦截器和处理器方法;

springmvc 配置log4j springmvc 配置流程_springmvc工作流程_03

6) 没有配置<mvc:default-servlet-handler/><mvc:annotation-driven/>,发送一个不存在资源的请求路径,mappedHandler为null。

http://localhost:8080/springmvc01/springmvc/helloworld1

springmvc 配置log4j springmvc 配置流程_springmvc_04


springmvc 配置log4j springmvc 配置流程_springmvc 配置log4j_05


4) 配置<mvc:default-servlet-handler/><mvc:annotation-driven/>,发送一个不存在资源的请求路径:

http://localhost:8080/springmvc01/springmvc/helloworld1

mappedHandler不为null,原因是当循环simpleUrlHandlerMapping时,当做静态资源处理,如下图:

springmvc 配置log4j springmvc 配置流程_springmvc 配置log4j_06

五、断点执行

springmvc 配置log4j springmvc 配置流程_核心控制器_07


关于SringMVC的工作流程就先说到这里,有什么问题及时交流。