目录
[Spring MVC](#Spring MVC)
[Spring MVC执行流程](#Spring MVC执行流程)
[Spring MVC封装参数](#Spring MVC封装参数)
[Spring MVC注解](#Spring MVC注解)
[@Controlle r和 @RequestMapping](#@Controlle r和 @RequestMapping)
SpringMVC
什么是MVC模型
MVC全称Model View Controller,是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分:
Model(模型):指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中,JavaBean对象,业务模型等都属于Model。
View(视图):用于展示模型中的数据的,一般为jsp或html文件。
Controller(控制器):是应用程序中处理用户交互的部分。接受视图提出的请求,将数据交给模型处理,并将处理后的结果交给视图显示。

Spring MVC
Spring MVC是一个基于MVC模式的轻量级Web框架,是Spring框架的一个模块,和Spring可以直接整合使用,我们使用的版本是Spring6,所以JDK需要17以上。SpringMVC代替了Servlet技术,它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。
案例
-
使用maven创建web项目,补齐包结构。
-
引入相关依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/>
</parent>
<groupId>org.bit</groupId>
<artifactId>Spring_MyBatis_Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Spring_MyBatis_Demo</name>
<description>Spring_MyBatis_Demo</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </path> </annotationProcessorPaths> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>
Spring MVC执行流程

Spring MVC的组件
- DispatcherServlet:前端控制器,接受所有请求,调用其他组件。
- HandlerMapping:处理器映射器,根据配置找到方法的执行链。
- HandlerAdapter:处理器适配器,根据方法类型找到对应的处理器。
- ViewResolver:视图解析器,找到指定视图。
组件的工作流程
- 客户端将请求发送给前端控制器。
- 前端控制器将请求发送给处理器映射器,处理器映射器根据路径找到方法的执行链,返回给前端控制器。
- 前端控制器将方法的执行链发送给处理器适配器,处理器适配器根据方法类型找到对应的处理器。
- 处理器执行方法,将结果返回给前端控制器。
- 前端控制器将结果发送给视图解析器,视图解析器找到视图文件位置。
- 视图渲染数据并将结果显示到客户端。
Spring MVC封装参数
简单数据类型
在Servlet中我们通过request.getParameter(name)
获取请求参数。该方式存在两个问题:
- 请求参数较多时会出现代码冗余。
- 与容器紧耦合。
而SpringMVC支持参数注入的方式用于获取请求数据,即将请求参数直接封装到方法的参数当中。用法如下:
-
编写控制器方法
// 封装为简单数据类型类型参数
@RequestMapping("/a1")
public void Main(String username,int age){
System.out.println(username);
System.out.println(age);
} -
访问该方法时,请求参数名和方法参数名相同,即可完成自动封装。
http://localhost:8080/a1?username=hhj\&age=20
简单对象
SpringMVC支持将参数直接封装为对象,写法如下:
-
编写实体类
-
编写控制器方法
public class Student {
private int id;
private String name;
private String sex;
}// 封装为简单对象类型参数
@RequestMapping("/a1")
public void Stu(Student student){
System.out.println(student);
} -
访问该方法时,请求参数名和对象参数的属性名相同,即可完成自动封装。
http://localhost:8080/a1?id=1\&name=hhj\&sex=male
关联对象
SpringMVC还可以将请求参数封装为关联对象,即对象的属性也是一个对象。写法如下:
-
编写实体类
public class Student {
private int id;
private String name;
private String sex;
private Address address; // 地址对象
// 省略getter/setter/tostring
}public class Address {
private String info; //地址信息
private String postcode; //邮编
// 省略getter/setter/tostring
}
2.编写控制器方法
// 获取关联对象类型参数
@RequestMapping("/a2")
public void objParam2(Student student){
System.out.println(student);
}
3.访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。
http://localhost:8080/a2?id=1\&name=hhj\&sex=male\&address.info=xian\&address.postcode=123456
简单数据类型集合
1.编写控制器方法
封装为简单数据类型集合,参数前必须添加@RequestParam注解
@RequestMapping("/c1/param4")
public void listParam(@RequestParam List<String> users){
System.out.println(users);
}
2.该方式也可以封装为简单数据类型数组:
@RequestMapping("/c1/param5")
public void listParam2(@RequestParam String[] users){
System.out.println(users[0]);
System.out.println(users[1]);
}
- 请求的参数写法
http://localhost:8080/c1/param4?users=hhj\&users=zpy
Map集合
同样,SpringMVC要想把参数封装到Map集合中,需要封装到有Map属性的对象中。
-
编写实体类
-
编写控制器方法
public class AddressMap {
private Map<String,Address> address;
// 省略getter/setter/tostring
}// 对象中包含map属性
@RequestMapping("/c1/param7")
public void mapParam3(AddressMap addressMap){
System.out.println(addressMap.getAddress());
}
3.请求的参数写法
参数的写法为:map属性名[键].值中的属性,例如:address[one].info
请求的路径如下:
编码后为:
参数类型转换器
前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:
// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
System.out.println(username);
System.out.println(age);
}
但在某些情况下,无法将字符串转为需要的类型,如:
@RequestMapping("/c1/param8")
public void dateParam(Date birthday){
System.out.println(birthday);
}
由于日期数据有很多种格式,SpringMVC默认只能转换2050/1/1
这样的日期格式。但假如前端传来的参数格式为2025-01-01
时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。
Spring MVC注解
@Controlle r和 @RequestMapping
@Controller
作用:标记控制器,将控制器交给Spring容器管理。
位置:类上方
位置:方法或类上方。用于类上,表示类中的所有控制器方法都是以该地址作为父路径。
属性:
-
value/path:请求路径
-
method:指定请求方式
-
params:规定必须发送的请求参数
-
headers:规定请求必须包含的请求头
@Controller
@RequestMapping("/c3")
public class MyController3 {
/**
* 访问路径是 /c3/a1
* 支持post和get请求
* 请求必须带有username参数
* 请求必须带有User-agen请求头
*
*/
@RequestMapping(path = "/a1",
method = {RequestMethod.POST, RequestMethod.GET},
params = {"username"},
headers = {"User-agent"})
public String annotation1(String username) {
System.out.println(username);
return "baizhan";
}
}
@RequestParam
作用:在控制器方法中封装请求参数
位置:方法参数前
属性:
/*
定义请求的参数名为name,默认值为sxt,不是必须的参数
*/
@RequestMapping("/a2")
public String annotation2(@RequestParam(name = "name",defaultValue = "sxt",required = false) String username) {
System.out.println(username);
return "baizhan";
}
请求URL的写法:http://localhost:8080/c3/a2?name=hhj
@RequestHeader、@CookieValue
@RequestHeader
作用:将请求头数据封装到控制器方法参数中
位置:方法参数前
@CookieValue
作用:将Cookie数据封装到控制器方法参数中
位置:方法参数前
/*
获取User-Agent请求头
获取JSESSIONID的Cookie值
*/
@RequestMapping("/annotation3")
public String annotation3(@RequestHeader("User-Agent") String userAgent, @CookieValue("JSESSIONID") String jSessionId){
System.out.println(userAgent);
System.out.println(jSessionId);
return "baizhan";
}
@SessionAttributes
作用:将Model模型中的数据存到session域中
位置:类上方
@Controller
@RequestMapping("/c4")
// 将模型中的name数据保存到session中
@SessionAttributes("name")
public class MyController4 {
@RequestMapping("/t1")
public String t1(Model model){
// model中保存name数据
model.addAttribute("name","中北
1111");
return "baizhan";
}
@RequestMapping("/t2")
public String t2(HttpSession session){
// 从session中获取name数据
Object name = session.getAttribute("name");
System.out.println(name);
return "baizhan";
}
}
@PathVariable
作用:在RESTful风格的URL中获取占位符的值
位置:方法参数前
属性:
value:获取哪个占位符的值作为参数值,如果占位符和参数名相同,可以省略该属性。
@Controller
@RequestMapping("/student")
// 模拟学生的增删改查控制器
public class MyController6 {
// 路径中的/{id}表示占位符,最后会封装到方法的参数中使用
// 删除学生
@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
public String deleteStudent(@PathVariable("id") int id){
System.out.println("删除id为"+id+"的学生");
return "baizhan";
}
// 如果占位符和参数名相同,可以省略@PathVariable中的value属性
// 根据id查询学生
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public String findStudentById(@PathVariable int id){
System.out.println("查找id为"+id+"的学生");
return "baizhan";
}
// 新增学生
@RequestMapping(value = "/{id}",method = RequestMethod.POST)
public String addStudent(@PathVariable int id, Student student){
System.out.println("新增id为"+id+"的学生");
System.out.println(student);
return "baizhan";
}
// 修改学生
@RequestMapping(value = "/{id}",method = RequestMethod.PUT)
public String updateStudent(@PathVariable int id, Student student){
System.out.println("修改id为"+id+"的学生");
System.out.println(student);
return "baizhan";
}
}