SpringMVC基本原理和配置
SpringMVC配置和基本原理
- SpringMVC基本原理
- SpringMVC配置
- 完整流程拆解
SpringMVC基本原理
SpringMVC 是基于 Servlet 的 MVC 框架,其核心是通过前端控制器 DispatcherServlet 协调各个组件完成请求处理与响应。
实际上 Spring MVC 本质就是一个servlet,是对原生的servlet进行了封装,在以前浏览器的每一次请求都需要写一个对应的servlet,现在只需要将浏览器的请求和响应交给DispatcheServlet进行统一的处理。
SpringMVC 整个流程的核心是 DispatcherServlet 作为中枢,协调 HandlerMapping、HandlerAdapter、ViewResolver 等组件完成请求处理与响应,通过松耦合的组件设计,实现了请求处理的灵活性和可扩展性。流程图如下:
流程详解:
用户在浏览器中输入 URL 或点击页面链接,浏览器会将请求封装为HTTP 请求报文(包含请求方法、URL、请求头、请求参数等信息),通过网络发送到目标服务器Tomcat,服务器 Tomcat 监听指定端口,接收到 HTTP 请求后,在 SpringMVC 中,所有请求都会先被 DispatcherServlet 处理,这是 SpringMVC 的核心前端控制器,DispatcherServlet 作为“中央处理器”,接收请求后不会直接处理,而是负责协调其他组件完成工作。DispatcherServlet 需要确定“谁来处理这个请求”,这一工作由 HandlerMapping 处理器映射器完成,HandlerMapping 的核心作用是根据请求的 URL、请求方法、请求参数等信息,通过预定义的映射规则(如@RequestMapping注解)找到对应的Handler,即 Controller 中处理请求的方法,找到 Handler 后,DispatcherServlet 并不会直接调用 Handler,而是通过 HandlerAdapter 处理器适配器执行 Handler,这是因为 Handler 可能是多种形式,HandlerAdapter 负责适配不同类型的 Handler,统一调用方式。HandlerAdapter 负责调用 Handler 即 Controller 中的目标方法,HandlerAdapter 会将请求参数绑定到 Handler 方法的参数上,Controller 方法调用 Service、Dao 等层处理业务生成处理结果,Controller 方法执行完成后,通常返回 ModelAndView 对象即包含 Model 数据和 View 名称,或直接返回数据如 JSON,注意需配合 @ResponseBody 注解。DispatcherServlet 拿到 ModelAndView 后,需要将 View 名称解析为具体的 View 实例(如 JSP、Thymeleaf 视图),这一工作由 ViewResolve 视图解析器完成。View 实例会接收 Model 中的数据键值对形式,并将数据填充到视图模板中,生成最终的响应内容,对于 JSON 响应是将返回的对象序列化为 JSON 字符串。DispatcherServlet 将渲染后的响应内容封装为 HTTP 响应报文,通过服务器返回给浏览器,浏览器解析响应内容并显示页面,完成整个流程。
SpringMVC配置
创建WEB工程,如图:
创建tomcat
下面我们来编写项目内容:
pom.xml
<!--版本锁定-->
<properties><spring.version>5.0.2.RELEASE</spring.version>
</properties><dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.0</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version>
</dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><!--SpringMVC--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!--servlet API--><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version><scope>provided</scope></dependency><!--日志--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring4</artifactId><version>3.0.9.RELEASE</version></dependency></dependencies>
Spring 框架的核心依赖:spring-context 是 Spring 的核心模块,提供 IoC 和 DI 功能,管理对象生命周期,spring-web 是 Spring 的 Web 模块,提供 Web 应用相关的基础支持,spring-webmvc 是 SpringMVC 框架,用于开发 Web 层(如控制器、请求映射、视图解析等),是 Java Web 开发的主流框架之一。
Jackson 库的核心组件,用于JSON 数据的序列化和反序列化:jackson-core 是核心底层库,处理 JSON 的解析和生成,jackson-annotations 提供注解支持,jackson-databind 是数据绑定包,基于前两个包实现 Java 对象与 JSON 的相互转换。
Java Web 开发的基础 API:servlet-api 是 Servlet 规范的 API,定义了 Servlet 的核心接口,jsp-api 是 JSP 规范的 API,用于开发动态网页,scope=provided 表示这两个依赖由 Web 服务器 Tomcat 在运行时提供,编译时仅需引用,无需打包到项目的 WAR/JAR 中。
Thymeleaf 是一个 Java 模板引擎,用于 Web 和独立环境,thymeleaf-spring4 是 Thymeleaf 模板引擎与 Spring 框架的集成包,用于 Web 应用的视图层开发,渲染 HTML 页面,替代 JSP 作为视图层技术,且支持 Spring 的特性。
web.xml
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"><!--在web.xml中配置Spring提供的过滤器类 --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><async-supported>true</async-supported><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--不拦截所有是html的页面请求--><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.html</url-pattern></servlet-mapping><!--配置前端控制器,对浏览器发送的请求进行统一处理--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--加载springmvc.xml配置文件的位置和名称,配置的是Spring配置--><init-param><!--contextConfigLocation:上下文配置路径,固定值--><param-name>contextConfigLocation</param-name><!--springmvc.xml:指的是配置文件的名称:需要配置springmvc.xml,在下面--><param-value>classpath:Spring.xml</param-value></init-param><!--配置启动加载--><load-on-startup>0</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--开启项目时打开的页面--><welcome-file-list><welcome-file>/index.html</welcome-file></welcome-file-list></web-app>
需要注意版本内容也需要按此修改
Spring 提供的CharacterEncodingFilter过滤器,用于统一设置请求和响应的字符编码,解决中文乱码问题。<filter-name>
是给过滤器名用于后续映射关联,<filter-class>
指定过滤器的实现类 Spring 提供的CharacterEncodingFilter,<async-supported>true</async-supported>
支持异步请求处理,<init-param>
始化参数,这里设置编码格式为UTF-8,<filter-mapping>
将过滤器映射到所有请求(<url-pattern>/*</url-pattern>
表示匹配所有路径),确保所有请求都经过编码处理。
让 Web 服务器 Tomcat 的默认 Servlet 直接处理 .html 结尾的静态页面请求,避免被 Spring MVC 的前端控制器拦截。default 是 Web 服务器内置的默认 Servlet,负责处理静态资源,配置 *.html 表示所有以 .html 结尾的请求由默认 Servlet 处理,无需经过 Spring MVC 的业务逻辑,提高静态资源访问效率。
DispatcherServlet 是 Spring MVC 的核心前端控制器,负责接收所有客户端请求,并协调 Spring MVC 的其他组件(如处理器映射器、控制器、视图解析器等)完成请求处理。<servlet-name>
设置控制器名称,用于关联 URL 映射,这里命名为dispatcherServlet,是 Spring MVC 的常规命名方式。<servlet-class>
指定 Spring MVC 提供的DispatcherServlet实现类,它是整个 Spring MVC 的核心,负责接收所有客户端请求并协调处理流程。<init-param>
设置 Spring MVC 配置文件的位置,contextConfigLocation 是固定参数名用于指定配置文件路径,classpath:spring.xml 表示在项目的类路径resources文件夹下加载spring.xml配置文件,该文件内包含 Spring MVC 的具体配置。load-on-startupt 用来标记这个servlet程序什么时候被加载,值是一个整数,表示被servlet加载的顺序。如果该标签的值是负数或者没有值,servlet不会在容器启动时初始化,而是等到第一次被请求时才触发初始化;如果值为正数或者0时,表示tomcat会在启动时加载该servlet,值越小,优先级越高,值相同时容器会自己选择加载顺序。
<url-pattern>/</url-pattern>
定义该 Servlet 负责处理的 URL 路径规则,这里的 / 表示所有请求除了已配置的 .html 静态资源都会被dispatcherServlet接收并处理,由它进一步转发到对应的 Controller(控制器)方法。
设置 Web 应用启动时默认打开的页面,这里指定为根路径下的index.html,当用户访问 Web 应用 http://localhost:8080/SpringMVC/时,若未指定具体资源,服务器会自动查找并返回 /index.html 默认页面。
编写spring.xml的配置文件
<!--配置spring创建容器时要扫描的包--><context:component-scan base-package="com.qcby"></context:component-scan><!--处理映射器--><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><!--处理器适配器--><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/><!--配置视图解析器--><bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><property name="templateEngine" ref="templateEngine"/></bean><!-- templateEngine --><bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"><property name="templateResolver" ref="templateResolver"/></bean><bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver"><property name="prefix" value="/html/" /><property name="suffix" value=".html" /><property name="templateMode" value="HTML5"/></bean><!-- JSON View --><beanclass="org.springframework.web.servlet.view.json.MappingJackson2JsonView"></bean><!-- 配置spring开启注解mvc的支持 默认就是开启的 ,要想让其他组件(不包含映射器、适配器、处理器)生效就必须需要配置了--><mvc:annotation-driven></mvc:annotation-driven>
配置 Spring 自动扫描com.qcby包及其子包下的类,会自动识别并注册带有@Controller、@Service、@Repository、@Component 等注解的类为 Spring Bean;
BeanNameUrlHandlerMapping(处理器映射器):负责将请求 URL 映射到对应的处理器 Controller;
SimpleControllerHandlerAdapter(处理器适配器):负责调用处理器的方法处理请求;
Thymeleaf 视图解析器配置,配置 Thymeleaf 模板引擎相关组件,用于解析 HTML 视图,设置字符编码为 UTF-8,避免中文乱码,以及指定了模板文件的位置,当控制器返回逻辑视图名(如"index")时,Thymeleaf 会通过以下规则解析为实际视图路径:prefix + 逻辑视图名 + suffix → /html/index.html 即从 Web 应用的/html目录下查找index.html文件并渲染。
JSON 视图配置,配置 Jackson 库支持 JSON 响应,将控制器返回的数据直接转换为 JSON 格式响应;
开启 Spring MVC 的注解驱动支持,默认是开启的,自动注册处理器映射器和适配器,支持@RequestMapping、@RequestBody、@ResponseBody等注解,简化开发无需手动配置大量 Bean;
HelloController.java
package com.qcby;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@Controller
public class HelloController {//处理器@RequestMapping(value = "/hello",method = RequestMethod.GET)public String hello(){return "hello";}//处理超链接发送出来的请求@RequestMapping(path = "/sayHello")public String sayHello(Model model){System.out.println("入门方法执行了2...");// 向模型中添加属性msg与值,可以在html页面中取出并渲染model.addAttribute("msg","hello,SpringMVC");// 配置了视图解析器后,写法return "suc";}
}
被 @Controller 注解标记的类会被 Spring 容器识别为一个控制器(Controller),负责处理用户发起的 HTTP 请求,结合配置文件中的组件扫描,Spring 会自动将这个类实例化为一个 Bean,纳入容器管理;
@RequestMapping 注解用于映射 HTTP 请求到控制器的具体方法,value = “/hello” 表示当客户端访问路径 http://服务器地址/项目名/hello 时,会触发该方法。method = RequestMethod.GET 指定只处理 GET 类型的请求,方法返回值表示要跳转的视图名称,结合配置文件中 Thymeleaf 的视图解析器实际会渲染 /html/hello.html 页面。
@RequestMapping(path = “/sayHello”)映射路径为 /sayHello 的请求,Model model 参数的作用是 Spring 会注入一个 Model 对象用于在控制器和视图之间传递数据,model.addAttribute(“msg”, “hello,SpringMVC”) 表示向模型中添加一个键值,把字符串 “hello,SpringMVC” 存到 Model 中命名为 msg,在视图页面中可以通过msg获取该值。返回值 return “suc” 结合视图解析器实际会渲染 /html/suc.html 页面。通过Model对象向视图传递数据,实现了控制器到视图的数据交互。
suc.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>成功</title>
</head>
<body>
<h1>Hello <b th:text="${msg}"></b></h1>
</body>
<script>
</script>
</html>
作为 Spring MVC 的视图,接收并展示控制器传递的数据,通过引入 Thymeleaf 命名空间,使用th:text 属性实现动态数据渲染,具体展示了从HelloController的sayHello()方法传递过来的msg变量的值。
完整流程拆解
从 “用户访问链接” 到 “页面显示结果”,用户在浏览器访问http://localhost:8080/SpringMVC/sayHello,整个流程如下:
步骤 1:用户发送请求,前端控制器DispatcherServlet接收
用户在浏览器输入/sayHello并回车,请求被发送到 Web 服务器Tomcat,服务器根据web.xml中dispatcherServlet 的配置 <url-pattern>/</url-pattern>
需要将所有请求都交给 dispatcherServlet 处理,因此,请求被转发给 DispatcherServle t前端控制器;
步骤 2:处理器映射器HandlerMapping找处理方法
DispatcherServlet 收到请求后,首先问处理器映射器:路径/sayHello该由哪个方法处理?映射器根据配置@RequestMapping(path = “/sayHello”),找到HelloController中的sayHello()方法,告诉DispatcherServlet 用这个方法处理;
步骤 3:处理器适配器 HandlerAdapter 执行控制器方法
DispatcherServlet 拿到映射结果后,交给处理器适配器,让它调用sayHello()方法,适配器会自动处理方法的参数,代码中的 Model model 适配器会创建一个Model对象传入方法,执行sayHello()方法的逻辑并往Model中存数据、返回逻辑视图名;
步骤 4:视图解析器ViewResolver解析实际页面路径
DispatcherServlet拿到返回的逻辑视图名suc后,交给视图解析器,suc对应的页面在哪?视图解析器根据spring.xml中的配置Thymeleaf 解析器,前缀prefix = “/html/” + 逻辑视图名suc + 后缀suffix = “.html” 拼接出实际路径 /html/suc.html,告诉DispatcherServlet页面在/html/suc.html;
步骤 5:视图View渲染并返回结果
DispatcherServlet找到/html/suc.html页面,交给Thymeleaf 模板引擎处理,模板引擎解析页面中的动态语法 <b th:text="${msg}"></b>
会从Model中取出msg的值替换到标签中,生成最终的 HTML 静态内容返回给浏览器,即用户看到页面内容为 Hello hello,SpringMVC。