【框架】SpringMVC
SpringMVC基础
SpringMVC概述
- SpringMVC技术与Servlet技术功能等同,均属于web层开发技术
- SpringMVC是一种基于Java实现MVC模型的一种轻量级Web框架
优点:
- 使用简单、开发便捷(相当于Servlet)
- 灵活性强
学习内容
- 请求与响应
- REST风格
- SSM整合
- 拦截器
学习目标
- 掌握基于SpringMVC获取请求参数与响应json数据操作
- 熟练应用基于REST风格的请求路径设置与参数传递
- 能够根据实际业务简历前后端开发通信协议并进行实现
- 基于SSM整合技术开发任意业务模块功能
MVC三层架构

小结
- SpringMVC是一种表现层框架技术
- SpringMVC用于进行表现层功能开发
SrpingMVC入门案例
案例步骤
①使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframwork</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
②创建SpringMVC控制器类(等同于Servlet功能)
//2.定义controller
@Controller
//2.1使用Controller定义Bean
public class UserController {
//2.2设置当前操作的访问路径
@RequestMapping("/save")
//2.3设置当前操作的返回值类型
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'springmvc'}";
}
}
③初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的Bean
//3.创建springmvc的配置文件,加载controller对应的Bean
@Configuration
@ComponentScan("com.zhm.controller")
public class SpringMvcConfig {
}
④初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
//定义一个servlet容器启动的配置类,在里面加载spring配置
//必须按照spring容器所支持的格式,即继承AbstractDispatcherServletInitializer
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置哪些请求归属springMVC处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
第④步简易化(点击展开隐藏代码)
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
案例分析
启动服务器初始化过程
- 服务器启动,执行ServletContainersInitConfig类,初始化web容器
- 执行createServletApplicationContext方法,创建了WebApplicationContext对象
- 加载SpringMvcConfig
- 执行@ComponentScan加载对应的bean
- 加载UserController,每个@RequestMapping的名称对应一个具体的方法
- 执行getServletMappings方法,定义所有的请求都通过SpringMVC

单次请求过程
- 发送请求localhost/save
- web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
- 解析请求路径/save
- 由/save匹配执行对应的方法save()
- 执行save()
- 检测到有@ResponseBody直接将save()方法的返回值作为响应请求返回给请求方
SpringMVC简介
Controller加载控制与业务bean加载控制
- SpringMVC相关bean(表现层bean)
- Spring控制的bean
- 业务bean(Service)
- 功能bean(DataSource等)
因此导致Spring和SpringMVC扫描混乱,解决方法:
- SpringMVC加载的bean对应的包均在controller包内
- Spring相关bean加载控制
- 方式一:扫描完整包,排除controller中的bean
- 方式二:扫描范围精确到service包、dao包等
- 不区分Spring与SpringMVC的环境,加载到同一个环境中
//方式一
@Configuration
@ComponentScan(value = "com.zhm",
excludeFilters = @ComponentScan.Filter(
//按注解排除
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
//方式二
@ComponentScan({"com.zhm.service","com.zhm.dao"})
PostMan(测试软件)简介
- PostMan是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件
- 作用:常用于进行接口测试
- 功能:模拟浏览器测试,可以记录测试,有点像git
请求与响应
请求映射路径
问题:团队多人开发,每个人设置的请求路径是不同的,但是相同就会冲突
解决:都加上模块名
对于同一模块下的不同响应都需添加相同的模块名,这是使用@RequestMapping注解添加请求访问路径的前缀

名称:@RequestMapping
功能:
请求响应 方法注解
路径前缀 类注解
请求参数
Get请求传参
- 普通参数:url地址传参,地址参数名和形参变量名相同,定义形参即可接收参数
Post请求参数
- 普通参数:form表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数

Post请求的中文乱码问题
在servlet配置类(ServletContainersInitConfig)中 添加:
//乱码处理
//过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
五种数据的传参
- 可以使用@RequestParam(" ")指定传参
和Mybatis中的@Param对象类似,可解决地址参数名和形参变量名不同时出现的问题 - (POJO类型)传参内容为实体类
类中成员变量与传参一一对应,即可自动转化为对象 - (嵌套POJO类型)参数内容为引用类型
那么输参,参数名应该为:引用对象名.属性名
使用方式与Mybatis中XML的注入差不多 - 参数内容为数组
传参时,key值相同

传入数组为 - 参数内容为集合
按照之前的写法,会把集合当作实体类处理
解决方法:加@RequestParam注解绑定参数关系,把信息作为参数放入

请求参数(传递json数据)
准备工作
- PostMan发送json数据

- SpringMVC开启json数据转化为对象的功能
SpringMvcConfig类使用@EnableWebMvc注解
json集合
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list → " + likes);
return "{'module':'list common for json param'}";
}
json对象(POJO)
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user → " + user);
return "{'module':'pojo for json param'}";
}

json数组(POJO)
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<String> likes){
System.out.println("list pojo(json)参数传递 list → " + likes);
return "{'module':'list pojo for json param'}";
}



日期类型参数传递
由于日期类型比较复杂,多变所以使用
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
其中pattern用来规定时间格式
//日期参数
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){
System.out.println("参数传递 date → " + date);
return "{'module':'data param'}";
}

原理

响应json数据
- 响应页面
- 响应文本数据
- 响应json数据(对象转json)
- 响应json数据(对象集合转json数组)

原理👇

转换Http消息的接口
重点
- jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
2. 注解@ResponseBody
作用:将对象数据转换成json数据
内部发挥总用的是`类型转换器(HttpMessageConverter接口)`
REST风格
简介
- REST(Representational State Tranfer),表现形式状态转换(访问网络资源的格式)
- 传统风格资源描述格式

- REST风格描述形式

- 传统风格资源描述格式
- 优点
- 隐藏资源的访问行为,无法通过地址得知资源是何种操作
- 书写简化
- 按照REST风格访问资源时使用
行为动作区分对资源进行了何种操作

- 根据REST风格对资源进行访问成为RESTful
入门案例
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete ..." + id);
return "{'module':'user delete'}";
}

解析
- "/users/{id}" REST风格,{id}大括号名称要与形参名称相同
- method = RequestMethod.DELETE,发送信息方式必须是DELETE
- @PathVariable
小结
简化开发
-
@RequestMapping中value属性中相同的部分使用@RequestMapping前缀,即写在类的外部 -
如果类中所有方法都有
@ResponseBody,则@ResponseBody写在类外部直接修饰类 -
如果类外部有
@ResponseBody和@Controller,那么两个注解直接拿@RestController注解代替

-
简化@RequestMapping

案例(基于RESTful页面数据交互)
访问静态资源(单独解析)
如果正常写的话,/pages/xxx走的是MVC,但是现在需要让它走Tomcat
解决方法(其中一种):
- 添加配置类

“放行”静态资源 - 让SpringMVC扫到配置类

实践步骤
小结:







浙公网安备 33010602011771号