SpringMVC全称为Spring Web model-view-controller (MVC) 框架,和其他webMVC框架一样都是围绕一个中心的servlet设计,由中心的servlet分发请求到controller和其他可以让web应用快速开发的功能。SpringMVC围绕DispatcherServlet设计,DispathcerServlet通过配置处理器映射(handler mapping),视图解析器(view resolver)等来转发请求到处理器。默认的处理器基于@Controller 和 @RequestMapping注解提供了广泛且自由的处理方法。除此意外,DispatcherServlet完全相融于SpringIOC容器,这使得我们可以在任何地方使用spring拥有的特性。
根据官网介绍及相关视频 自己画流程图如下:
1.分发url到处理器映射器寻找到对应的handler映射
2.处理器适配器根据映射寻找对应的处理器handler,即控制器。返回的model及对应的业务逻辑均在controller类中实现。
3.拿返回的model寻找视图解析器进行解析渲染,然后返回对应的页面。
需要在web.xml中配置注册Springframework中DispatcherServlet,也可以自己定义重写DispatcherServlet。这里直接注册框架包中的DispatcherServlet,和注册Servlet一样。
在DispatcherServlet初始化的时候,SpringMVC会去web应用的WEB-INF目录下去寻找一个名为【servlet-name】-servlet.xml的文件,并且创建这个文件里边的bean,并在全局范围内用这些bean重写覆盖名称相同的bean。【servlet-name】-servlet.xml 这个文件也可以放在其他目录下,但是在DispatcherServlet初始化时要保证可以找到这个文件。
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 关联一个springmvc的配置文件 [servlet-name(即上面标签内的内容)]-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-servlet.xml</param-value> </init-param> <!-- 启动级别--> <load-on-startup>1</load-on-startup> </servlet> <!-- / 匹配所有的请求 不包括 jsp文件--> <!-- /* 匹配所有请求 包括 jsp文件--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
上面知道在DispatcherServlet初始化时会从配置文件加载并覆盖重名的实体类,如果没有明确定义对应的实体类,DispatcherServlet自己有维护一个默认的实体类的实现,在org.springframework.web.servlet包下的DispatcherServlet.properties文件中可以查看。所有这些特殊的实体类都会有自己合理的默认项,所以在使用过程中你可能需要修改这些类的默认配置来满足自己的需要。比如常见的视图解析器 InternalResourceViewResolver 我们通常会修改他的prefix属性 来定义视图文件的父位置。
以上默认配置中定义的实体类在整个web应用中都是可以使用的,即全局可以使用。在Spring中ApplicationContext实例是全局的,在WebMVC框架中每一个DispatcherServlet都有自己的WebApplicationContext,WebApplicationContext继承了在rootWebApplicationContext中定义的所有的实体类,rootWebApplicationContext中包含了所有在上下文和Servlet实例中需要共享的基础类。引用官网的结构如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 关联一个springmvc的配置文件 [servlet-name(即上面标签内的内容)]-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-servlet.xml</param-value> </init-param> <!-- 启动级别--> <load-on-startup>1</load-on-startup> </servlet> <!-- / 匹配所有的请求 不包括 jsp文件--> <!-- /* 匹配所有请求 包括 jsp文件--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
处理器映射器和适配器不显式声明不影响程序运行,会走默认配置。视图解析器如不写 需在controller中设置视图名称时写全路径。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 处理映射器 可省略不影响程序运行 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 处理适配器 可省略不影响程序运行--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 后缀--> <property name="suffix" value=".jsp"/> </bean> <!-- Handler--> <bean name="/test" class="com.test.study.TestController"/> <bean name="/another" class="com.test.study.AnotherController"/> </beans>
package com.test.study; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AnotherController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("another");// 相当于/WEB-INF/jsp/another.jsp modelAndView.addObject("name","another"); modelAndView.addObject("age",13); return modelAndView; } }
<%-- Created by IntelliJ IDEA. User: mqh Date: 2021/6/10 Time: 10:12 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>anothercontroller</title> </head> <body> <form action="test" method="post"> 姓名:<input type="text" name="name" value="${name}"> 年龄:<input type="text" name="age" value="${age}"> <input type="submit"> </form> </body> </html>