通常,Web 应用的工作流程如下:
-
用户通过浏览器访问前端页面;
-
前端页面通过异步请求向后端服务器发送数据;
-
后端采用“表现层-业务层-数据层”三层架构进行开发:
- 表现层接收页面请求
- 将请求参数传递给业务层
- 业务层访问数据层,获取所需的用户数据
-
表现层将用户数据转换为 JSON 格式,并返回给前端;
-
前端接收并解析数据,将其组织成最终页面信息,再发送给浏览器展示。
在这个后端架构中,表现层过去使用 Servlet 技术进行开发,现在则采用了 SpringMVC 技术作为替代。SpringMVC 是一个基于 Java 实现 MVC 模型的轻量级 Web 框架,相比于传统的 Servlet,SpringMVC 具有以下优点:
- 使用简单:开发人员可以更快速地上手,减少了学习成本
- 灵活性强:能够更方便地适应不同业务需求,支持多种配置和扩展方式
快速入门
使用 SpringMVC 框架的开发主要分为四个步骤。在此之前,首先创建一个新项目。这里使用 IDEA 创建一个新的 Module,Archetype 选择 maven-archetype-webapp
:
在新创建项目基础上,对项目进行瘦身:调整 pom.xml 文件中的内容,删除非必须项和 webapp/WEB-INF 下的 web.xml
文件:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.it</groupId><artifactId>spring_mvc_01</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies></dependencies></project>
接着,打开 Project Structure,在 src 文件夹下创建源码目录。右键 main 目录,选择 New Folder 创建 java
文件夹,将 java
文件夹指定成源码目录(选中 java
文件夹,点击 Mark as 处的 source):
(1)导入 SpringMVC、Servlet 坐标和 Tomcat 插件
SpringMVC 项目需要引入相关的依赖和插件。在 pom.xml 文件中导入 SpringMVC、Servlet 坐标依赖和 Tomcat 插件。注意:为了防止 Servlet 导入与 Tomcat 插件之间存在冲突,这里将 scope 项配置成 provided
:
<dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
<build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8080</port><path>/</path></configuration></plugin></plugins>
</build>
(2)创建 SpringMVC 控制器类
在 java
文件夹下创建 com.it.controller.UserController 类。在该类基础上:
- 使用
@Controller
将类声明为 Bean 对象; - 定义处理请求的方法,这里以返回 String 类型的 save 方法为例;
- 使用
@RequestMapping
设置当前处理方法的访问路径; - 使用
@ResponseBody
设置当前控制器方法响应内容为当前返回值,无需解析,即将 save 方法返回的内容整体作为响应的内容:
@Controller
public class UserController {@RequestMapping("/save")@ResponseBodypublic String save() {System.out.println("user save ...");return "{'module': 'springmvc'}";}
}
(3)设置 SpringMVC 加载对应的 Bean 对象
首先,在 com.it.config 下创建 SpringMvcConfig 类。接着,使用 @Configuration
指定该类为配置类,再使用 @ComponentScan
指定需要扫描的包,以此加载 controller 对应的 Bean 对象:
@Configuration
@ComponentScan("com.it.controller")
public class SpringMvcConfig {
}
(4)设置 Tomcat 启动配置,加载 SpringMvcConfig 类
在 com.it.config 中定义一个 Servlet 容器启动的配置类 InitConfig,并且在该类中加载 Spring 和 SpringMVC 的配置。InitConfig 配置类需要继承 AbstractDispatcherServletInitializer 类,并实现三个抽象方法:
- 在
createServletApplicationContext
方法中加载 SpringMVC 配置; - 在
getServletMappings
方法中设置归属 SpringMVC 处理的请求路径; - 在
WebApplicationContext
方法中加载 Spring 配置:
public class InitConfig extends AbstractDispatcherServletInitializer {// 用于加载 SpringMVC 容器配置@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringMvcConfig.class);return ctx;}// 设置哪些请求归属 SpringMVC 处理@Overrideprotected String[] getServletMappings() {// 设置所有的请求归属 SpringMVC 处理return new String[]{"/"};}// 加载 Spring 容器配置@Overrideprotected WebApplicationContext createRootApplicationContext() {return null;}
}
完成上述四个步骤后,启动程序。点击 Add Configuration 创建 Run Configurations,设置 tomcat7:run
:
运行程序后,访问 http://localhost:8080/save
,返回之前处理请求方法中的返回内容 {'module': 'springmvc'}
,则启动成功。
工作流程
在快速入门案例中,涉及到了启动服务器和单次请求发送的操作,工作流程如下:
(1)启动服务器初始化
- 服务器启动,执行 Initconfig 类,初始化 Web 容器
- 执行 createServletApplicationContext 方法,创建 WebApplicationcontext 对象
- 加载 SpringMvcConfig 配置类
- 执行
@Componentscan
加载对应的 Bean - 加载 Usercontroller,每个
@RequestMapping
名称对应一个具体方法 - 执行 getservletMappings 方法,定义所有请求都通过 SpringMVC 框架
(2)发送单次请求
- 发送请求
localhost/save
- Web 容器发现所有请求都经过 SpringMVC,将请求交给 SpringMVC 处理
- 解析请求路径
/save
- 由
/save
匹配执行对应的 save 方法 - 检测到有
@ResponseBody
,直接将 save 方法返回值作为响应求体返回给请求方