SpringMVC
- 曾经:
Model1
Model2
三层架构 (业务访问层[ 数据展示层/数据控制层 ]+业务处理层+数据访问层)
业务访问层:数据展示层JSP+数据控制层Servlet - 现在:
SpringMVC对业务访问层进行封装处理,类似于这样
SpringMVC的优点
- 基于组件技术,组件就是java类,并且与Spring技术紧密结合(Spring的一部分)
- 编写阶段不依赖Servlet,运行阶段自动依赖Servlet
- 支持视图技术 JSP PDF Excel
- 支持Restful的风格的访问请求
- 易于扩展,扩展使用SpringBoot快速搭建
使用
【1.Dependence依赖 与 Plugin 插件】
<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>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
【2.注册容器】将SpringContext&SpringMVCContext(Web容器) 容器交给Servlet
//web容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
🙄🙄🙄当然推荐使用升级版简化格式🙄🙄🙄
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
// 处理POST 中文请求乱码问题
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
<!--处理:Get访问路径编解码字符集-->
<uriEncoding>UTF-8</uriEncoding>
}
【3.注解开发】
Web容器配置类
@ComponentScan()
@Configuration
@EnableWebMvc 开启MVC-JSON转换器
.
@ResponseBody 将 return 资源封装为响应体对象
@Controller 标记为视图访问层
(便于后期SpringWeb容器与Spring容器 @Servce & @Reposity 组件排除)
升级版:@RestController
.
@RequestMapping(用于类和方法上,可以设置多级资源访问目录”/“,或"/{id}"试图获取路径变量)
方式一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean
方式二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中
.
【请求参数获取】
直接获取:
(仅能获取 年、月、日 日期类型)
.
@RequestParam URI资源参数
required:是否为必传参数
defaultValue:参数默认值
.
@PathVailable 路径变量
.
@RequestBody (URL From表单数据 & JSON Body转换)(String→Integer)(json → Mao/Conllcetion)(json → POJO)
(请求参数与java形参类型不一致,无法封装,提供了类型转换顶级converter接口实现,需要导入转换器)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
【日期类型参数】日期格式转换(String → Date)
@DateTimeFormat
直接隐式获取:
(默认格式yyyy/MM/dd)
(仅能获取 年/月/日 - 日期类型)
.
自定义格式获取获取:
@DateTimeFormat(pattern=“yyyy/MM/dd HH:mm:ss” ) Date date_1
【响应类型】
响应动态资源或静态资源
return “page.jsp”;
.
文本数据响应
(中文必定发生乱码:
解决一:响应produces参数 设置MIME类型
方式二:设置Hander请求头Cookie Accept:Application/json;charset=UTF-8)
return “String字符串”
.
JSON类型
直接返回对象
return Object
RESTful开发(表示状态转移)推荐使用
GET查询 POST添加 PUT修改 DELTE删除
根据不同的请求方式,进行匹配将资源进行发送
@RequestMapping(method = RequestMethod.GET)
@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
@RequestMapping(method = RequestMethod.POST)
@RequestMapping(method = RequestMethod.PUT)
@RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
使用RESTful风格,在模块一级资源路径后加 ‘s’
【简化版】,快速开发
@GetMapping
@GetMapping("/{id}")
@PostMapping
@PutMapping
@DeleteMapping("/{id}")
路径变量获取占位符与资源配置占位符不同
SpringMVC四大核心组件
-
DispatcherServlet(前端控制器)
MVC模式中的Controller,DispatcherServlet是整个流程控制核心中心,由它调用其他组件处理用户请求
相当于注册中心 -
HandlerMapping(处理器映射器)
负责根据用户请求找到Handler以及处理器
Springmvc提供了不同的映射器实现不同的映射方式 [ 配置文件方式 实现接口方式 注解方式 ] ,根据这些不同方式,通过处理器适配器配对 -
HandlerAdapter(处理器适配器)
对处理器进行执行,适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行处理 -
ViewResolver(视图解析器)
负责将处理结果生成View试图,ViewResolver首先根据逻辑视图名解析成物理试图名既具体的页面地址,生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户
什么是View视图?
SpringMVC框架提供的很多View视图类型的支持
常用视图是Jsp。一般情况下需要通过页面标签或页面模板技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面
什么是Handler处理器?
继DispatcherServlet前段控制器的后端控制器,在DispatcherServlet的控制下Handler(Controller)对具体的用户请求进行处理。由于Handler涉及到具体用户的业务,所以一般情况需要程序员根据业务需求开发Handler
SpringMVC的工作流程
-
DispatcherServlet
接收到页面用户请求 -
DispatcherServlet
对请求URL进行解析,得到请求资源标识符
根据URL,调用HandlerMapping
获取该Handler配置的所有相关对象
(包括Hanlder对象
以及Hanlder对象对应的拦截器)
最后HandlerExecutionChain处理器执行链对象形式返回 -
DispatcherServlet
获得Handler
,根据后端操作方式进行适配选择HandlerAdapter
-
提取
Request
中的模型数据,填充到Handler
入参,开始执行Handler
填充Handler
入参过程中,根据配置xml做了一些额外的填充操作HttpMessageConveter对象:将请求数据转换成对象,将对象转为执行的响应数据
数据转换:请求消息进行数据转换,String转Integer、Double等
数据格式化:字符串类型格式化为日期类型,需要提供转换格式
数据验证:验证数据有效性,验证结果存储到BingdingResult捆绑结果集或Error中 -
Handler
执行完毕后,向DispatcherServlet
返回一个ModelAndView对象
-
根据返回的
ModelAndView对象
,选择发送给一个合适的ViewResolver
(第三方视图解析器必须已经注册到SpringIOC中) -
ViewResolver
结合Model
和View
,来渲染视图并返回给DispatcherServlet
-
最终将渲染的结果响应给客户端页面
项目中出现Bug如何快速定位?
- 请求没有被Handler接收到:检查REquestMapping映射和请求URL
- 请求参数没有传递到控制器方法:检查参数的参数类型与格式
- 控制器正常执行请求,但是视图显示404:检查视图解析器的配置
了解SpringMVC工作流程,更能快速的Debug定位
SpringMVC获取Form表单的方式有哪些?
- 借助原始ServletAPI的HttpServletRequest对象
Handler的方法,添加HttpServletRequest类型入参
一对一通过HttpServletRequest.getParameter()获取请求数据
一对多通过getParameterValues()
多对多通过getParameterMap()
需要对Servlet进行了解,违背了SpringMVC的旨意
- 借助Handler方法的形参,进行参数绑定
Handler的方法,添加参数来接受表单的数据
按照不同类型的键值对,通过不同方式的参数格式绑定绑定
请求参数必须是key=value键值对格式类型
- 借助Handler方法,接收实体类类型参数
使用@RequestBody注解获取全部请求体,配合Jackson工具包实现Json数据格式转换为实体类类型,要求Json的Key必须和实体类字段保持一致
对请求参数Json格式数据进行获取
SpringMVC如何参数绑定?
参数绑定:主要通过Handler方法的接收请求的形参有关
前端页面请求参数有两种格式:
key=value键值对格式
Json字符串格式
- 基本类型 和 String类型
要求:handle方法形参名
必须和表单元素url请求中name属性请求传参名
一致
前端:提交表单数据url?name=张三&age=18
后端:方法形参(String name ,Integer age)
如果
请求参数名
和Handler方法参数名
不一致时,使用@requsetParam(“表单字段名”)来获取表单参数
- 实体类类型
要求:handler方法形参
必须是实体类类型
前端:表单提交字段name属性名和实体类形参一致
后端:形参实体类名与前端name属性一致
主要通过Getter和Sertter方法绑定,所有实体类的字段名需要Getter和Setter方法后保持一致
-
实体类类型关联实体类类型(属性中包含实体类型)
要求:
前端:表单提交字段name属性名和实体类形参一致,而属性实体类类型,需要用关联实体类名小写.关联实体类属性名
后端: -
实体类关联集合类型
List:
前端:实体类属性名与属性名对应,用集合名[集合下标].索引名
后端:实体类属性中包含一个LIst集合
Map:
前端:实体类属性名与属性名对应,用集合名[‘key名’].values名
后端:实体类属性中包含一个Map集合 -
使用原始ServletAPI进行操作
要求:绑定参数必须是键值对格式如:url?name=张三&age=18,json字符串格式无效
绑定参数是,处理器适配器会调用参数绑定组件的实现参数绑定
SpringMVC 数据帮固定底层如何实现的?
RequestParamMethodArgumentResovler类中resolveName()方法,该方法调用原生ServletAPI中的HttpServletRequest对象中getParameterValues(name)方法来获取参数
Spring与SpringMVC常用注解
-
@Component:标记当前类为Spring的一个组件,会进入IOC容器注册
并且可以设置Id别名属性,默认为简单类名小写字符串
衍生注解:@Controller控制层组件 @Service业务层组件 @Repository数据访问层组件 -
@RequestMapping 标记Handler类以及方法,作为Dispatcher请求地址的映射
类:父类路径
类与方法:父路径+子路径 组合
[web.xml配置文件属性支持]
value用于配置访问URL的映射,唯一,和Path属性作用一样
method请求方式限定
params限定必须有指定参数名称
headers限定消息头中必须指定的消息头
consumes限定请求参数Json的格式类型
produces指定生成响应数据的类型(MIME类型)
@RequestParm 指定请求参数赋值给方法的形参
当请求参数名和控制器传参数名不一致时使用
@PathVariable 获取URL中的动态参数
只能获取Get 的URL后面的部分
@RequestBody 读取Request请求的body部分数据,获取请求体的内容
可以进行参数绑定,Json格式数据无法数据绑定,必须配合Jackson工具包解析
@ResponseBody 将Handler方法响应数据
用IO流响应给客户端,将数据返回,需要配合Jacson工具包
@RestController=@Controller+@ResponseBody
@Transancitonal
标记的类 全部方法可以支持事务
标记的方法 当前方法支持事务,比如只读