目录
简介
MVC简介
MVC是软件架构思想,将软件按照模型,视图,控制器划分
- M:Model:模型层,指工程中的JavaBean,作用是处理数据
- JavaBean分为两大类
- 实体类Bean:专门存储业务数据的,如Student,User等
- 业务处理Bean:指Service(处理业务逻辑)或Dao(查询数据数据库,建立持久化数据操作的)对象,专门用于处理业务逻辑和数据访问
- JavaBean分为两大类
- V:View:视图层,指工程中的html和jsp等页面,作用是与用户进行交互,展示数据
- C:Controller:控制层,指工程中的servlet,作用是接收请求和响应浏览器
MVC工作流程
用户通过视图层View发送请求到服务器,在服务器中被Controller接收,Controller调用响应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果,找到相应的View视图层,渲染数据后最终响应给浏览器
SpringMVC简介
MVC :Model + View + Controller
SpringMVC框架主要解决了V和C相关的问题,并且,在目前主流的前后端分离的开发环境下,也不再需要服务器处理V相关的问题,所以,在项目中使用Spring MVC框架更多的适用于解决C相关的问题.
SpringMVC具体解决了:接收请求,响应结果,统一处理异常.
SpringMVC是Spring的一个后续产品,是Spring的子项目
SpringMVC为表述层开发提供了一套完整的解决方案
注:三层架构分别为:
- 表述层(表示层)--表述层表示前台页面和Servlet
- 业务逻辑层
- 数据访问层(持久层)
SpringMVC的特点
- Spring家族的原生产品,与IOC容器(IOC容器是一种设计思想,将设计好的对象交给控制器)等基础设施无缝对接
- 基于原生Servlet,通过功能强大的DispatcharServlet,对请求和响应进行统一管理
- 对于表述层细分领域需要解决的问题全方位覆盖,提供全面解决方案
- 代码简洁,大幅提高开发效率
- 内部组件化程度高,可插式即插即用,想用什么功能配置对应相当组件即可
- 性能卓越,尤其适用现代大型,超大型互联网项目要求
- Spring内置框架
SpringMVC工作流程的简单总结
浏览器发送请求,若请求地址符合前端控制的url-pattern,请求就会被DispatcharServlet处理.前端控制器会读取SpringMVC的核心配置文件,通过扫描组件找到控制器,将请求地址和控制器中@RequestMapping注解的Value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法.处理请求的方法需要返回一个字符串的视图名称,该视图会被视图解析器解析,加上前缀和后缀组成视图路径,通过Thymeleaf对视图进行渲染,最终转发到视图的对应界面
图是找的别人的,具体是谁的我给忘了,他画的挺好就拿过来用了
Spring MVC的5大核心组件
- DispatcherServlet :统一接收请求,并分发,组织处理请求的流程
- HandlerMapping :是个接口,用于记录请求路径与控制器的映射关系
- Controller :是自定义的,用于处理请求
- ModelAndView :是控制器处理请求的方法的返回结果,用于封装视图组件名称与数据(仅用于非响应正文时)
- ViewResolver :根据视图组件名称确定实际应用的视图组件
处理请求
关于控制器类
- 必须在组件扫描的包下
- 在类上添加@Controller注解,也可以使用@RestController注解(@RestController注解使用了@Controller和@ResponseBody作为元注解)
- 推荐在类上使用@RequestMapping注解配置请求路径部分
关于处理请求的方法
- 在方法上添加@RequestMapping配置路径
还可以使用@GetMapping,@PostMapping等注解,限制请求方式
配置路径时可以使用{}格式的占位符 例如:@RequestMapping(“/categories/{id}/delete”)
有必要的话,配置此注解的produces属性,指定响应的文档类型 例如:@RequestMapping(value=”list”,produces=”application/json;charset=utf-8}
- 方法应该是public权限
- 方法的返回值
- 没有使用@ResponseBody时
- 使用String表示视图组件名称
- 使命MpdelAndView封装视图组件名称与数据
- 使用@ResponseBody时
- 使用String表示响应的文本,默认是HTML源代码
- 使用自定义的数据类型,将响应JSON格式
- 需添加jackson-databind依赖
- 在非Spring Boot项目中
- 没有使用@ResponseBody时
在基于直接的配置时,需要在配置类上添加@EnableWebMvc注解
在基于XML的配置时,需要在XML配置文件中添加<cnnotation-deive/>
4. 方法的名称是自定义的
5. 方法的参数列表 :
(1) 可按需添加参数
① 可逐一声明若干个参数 :可以在参数上添加@RequestParam,配置参数名,是否必须,默认值(通常不需要使用此注解)
② 可将多个参数封装为自定义数据类型,并使用自定义数据类型作为参数
1) 如果要求客户端提交的请求参数是KSON格式的,必须添加@RequestBody
2) 如果客户端提交的请求参数是FromData格式的,不可以添加@RequestBody
3) 如果是URL中占位符对应的添加,需要添加@PathVariable注解
③ 请求与响应 :可按需添加HttpServletRequest,HttpServletResponse,HttpSession
④ Spring容器中的Spring MVC的相关对象 :可按需添加ModelMap(仅用于非响应正文时)
⑤ Spring Security上下文中的认证对象的当事人,需添加@AuthenticationPrincipal注解
(2) 多个参数时,不区分各参数的先后顺序
统一处理异常
- 关于统一处理异常的类
- 必须在组件扫描的包下
- 在类上添加@ControllerAdvice注解 也可以使用@RestControllerAdvice(使用了ControllerAdvice和ResponseBody作为元注解)
- 关于统一处理异常的方法
- 需要添加ExpetionHandler注解
- 可以在注解参数中指定需要处理的异常类型(此注解参数是数组,可指定多个异常类型)
- 如果未指定注解参数,则处理的异常类型以方法的参数中的异常类型为准
- 方法应该是public权限
- 方法的返回值类型可参考处理请求的方法的返回值进行涉及
- 方法的名称是自定义的
- 方法的参数列表
- 必须添加异常类型的参数(表示被处理的异常)
- 可按需添加HttpServletRequest,HttpServletResponse等少量特定类型的参数
- 可以有多个处理异常的方法,但各方法处理的异常类型必须不同
- 各方法处理的异常类型允许存在继承关系,例如A方法处理NullPointerException,B方法处理RuntimeExcpetion.C方法处理Throwable
- 强烈推荐一个处理Throwable的方法,避免有异常不被处理
- 需要添加ExpetionHandler注解
Spring MVC拦截器
关于拦截器
- 建议在组件扫描的包下,并添加组件注解
- 必须实现HandlerInterceptor接口
- 可以实现有多个拦截器,形成拦截器链
关于拦截器的方法
- preHandle() :在控制器之前执行,如果此方法返回ture,表示放行,如果返回false,表示组织向后运行
- postHandle() :在控制器之后执行
- afterCompletion :在处理完请求之后,即将响应之前执行
关于拦截器的配置
- 必须实现了WebMvcConfigurer接口的Spring MVC配置类通过addInterceptors()方法注册
- 可以配置拦截路径,排除未例外的路径
- 配置路径时可以使用 * 通配路径中1个层级的任意资源名
- 例如:/categories/* 可以匹配/categories/add,/categories/list,不可以匹配/categories/1/delete
- 配置路径时可以使用 ** 通配路径中n个层级的任意资源名,例如/categories/** 可以匹配/categories/add,/categories/list,/categories/1/delete
- 配置路径时可以使用 * 通配路径中1个层级的任意资源名
关于拦截器的作用
- 处理多个请求时,都需要执行相同的代码片段,则可以将这些代码片段放在拦截器中统一执行 :例如验证用户是否已经登录
- 许多需要通过拦截器实现的功能,均有专门的框架来处理 :例如用户的认证和授权,可使用Spring Security框架来处理
关于拦截器和过滤器的区别
- 拦截器是Spring MVC框架中的组件,而过滤器是JavaEE中的组件
- 仅当使用Spring MVC时可以使用拦截器
- 只要是Java Web工程,均可以使用过滤器
- 拦截器的配置更自由 :拦截器可以配置排除为例外的路径,而过滤器不可以
- 拦截器的首次执行在Controller组件之前,锅炉器在所有组件之前 由于过滤器执行时间特别早,在某些功能的处理上具有不可替代性
@RequestMapping注解
功能
@RequestMapping注解:请求映射.作用就是将请求和处理请求的控制器关联起来,建立映射关系
位置
- 标识在类:设置映射的请求路径初始位置
- 标识在方法:设置映射的请求路径的具体位置
value属性
- value属性通过请求的请求地址请求映射
- value属性是一个字符串类型数组,表示该请求映射能够匹配多个请求地址所对应的请求
- @RequestMapping(
- value = {"/testRequestMapping", "/test"}
- )
- public String testRequestMapping(){
- return "success";
- }
- value属性必须设置,至少通过请求地址匹配请求映射
method属性
@RequestMapping注解的method属性通过请求的请求方式(get或post)匹配请求映射
@RequestMapping注解的method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配
多种请求方式的请求
若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错
405:Request method 'POST' not supported
params属性
@RequestMapping注解的params属性通过请求的请求参数匹配请求映射
@RequestMapping注解的params属性是一个字符串类型的数组,可以通过四种表达式设置请求参数
和请求映射的匹配关系
"param":要求请求映射所匹配的请求必须携带param请求参数
"!param":要求请求映射所匹配的请求必须不能携带param请求参数
"param=value":要求请求映射所匹配的请求必须携带param请求参数且param=value
"param!=value":要求请求映射所匹配的请求必须携带param请求参数但是param!=value
- @RequestMapping(
- value = {"/testRequestMapping", "/test"}
- ,method = {RequestMethod.GET, RequestMethod.POST}
- ,params = {"username","password!=123456"}
- )
- public String testRequestMapping(){
- return "success";
- }
注:
若当前请求满足@RequestMapping注解的value和method属性,但是不满足params属性,此时
页面回报错400:Parameter conditions "username, password!=123456" not met for actual
request parameters: username={admin}, password={123456}
headers属性
@RequestMapping注解的headers属性通过请求的请求头信息匹配请求映射
@RequestMapping注解的headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信
息和请求映射的匹配关系
"header":要求请求映射所匹配的请求必须携带header请求头信息
"!header":要求请求映射所匹配的请求必须不能携带header请求头信息
"header=value":要求请求映射所匹配的请求必须携带header请求头信息且header=value
"header!=value":要求请求映射所匹配的请求必须携带header请求头信息且header!=value
若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面
显示404错误,即资源未找到
@RequestBody注解
当客户端提交请求时,使用整个对象(this.ruleForm)作为请求参数时,服务器端接收请求参数时必须添加@RequestBody注解:
如果未添加此注解,则服务器端收到的各项参数均是null值!
**提示:**当添加了@RequestBody后,在Knife4j的API文档中,调试界面不再提供各项请求参数的输入框,而是自行组织JSON格式的请求参数进行调试.
当服务端没有在请求参数之前添加@RequestBody时,客户端提交的请求参数必须是FromData格式的,例如:
- let fromData = 'name=Xxx&description=Xxx&sort=99';
如果不是FromData格式的,服务器会响应415错误,且服务器的控制台会提示错误信息,例如:
- 2023-03-28 17:32:39.639 WARN 37160 --- [nio-9080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported]
注解
1.@ResponseBody
添加在方法上,标记此方法是“响应正文”的,
添加在类上,标记此类中所有方法都是“响应正文”的
2.@RestController
添加在类上,标记此类是一个“响应正文”的控 制器类
3.@RequestMapping
添加在类上,也可以添加在处理请求的方法上,通常用于配置请求路径
4.@GetMapping
添加在方法上,是将请求方式限制为 GET 的@RequestMapping
5.@PostMapping
添加在方法上,是将请求方式限制为 POST 的@RequestMapping
6.@DeleteMapping
添加在方法上,是将请求方式限制为 DELETE 的@RequestMapping
7.@PutMapping
添加在方法上,是将请求方式限制为 PUT 的@RequestMapping
8.@RequestParam
添加在请求参数上,可以:
(1). 指定请求参数名称
(2). 要求必须提交此参数
(3). 指定请求参数的默认值
9. @PathVariable
添加在请求参数上,用于标记此参数的值来自URL中的占位符,如果URL中的占位符名称与方法的参数名称不同,需要配置此注解参数来指定URL中的占位符名称
10.@RequestBody
添加在请求参数上,用于标记此参数必须是对象格式的参数,如果未添加此注解,参数必须是FormData格式的
11.@ExceptionHandler
添加在方法上,标记此方法是处理异常的方法,可以通过配置注解参数来指定需要处理的异常类型,如果没有配置注解参数,所处理的异常类型取决于方法的参数列表中的异常类型
12.@ControllerAdvice
添加在类上,标记此类中特定的方法将作用于每次处理请求的过程中
13.@RestControllerAdvice
添加在类上,是 @ControllerAdvice 和@ResponseBody 的组合注解
SpringMVC支持ant风格的路径
?:表示任意的单个字符
*:表示任意的0个或多个字符
**:表示任意的一层或多层目录
注意:在使用**时,只能使用/**/xxx的方式
SpringMVC支持路径中的占位符
原始方式:/deleteUser?id=1
rest方式:/deleteUser/1
SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服
务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在
通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参