SSM - SpringMVC
本文最后更新于:5 个月前
SSM框架 - SpringMVC
SpringMVC
简介-入门
SpringMVC是一种基于Java实现MVC模型的轻量级web框架
SpringMVC技术与Servlet技术功能等同,均属于web层开发技术
优点
使用简单,开发便捷(相比于servlet)
灵活性强
IDEA 创建SpringMVC项目
https://www.bilibili.com/video/BV1Fi4y1S7ix?p=44
SpringMVC入门案例
1、使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标
2、创建SpringMVC控制器类(等同于servlet功能)
3、初始化SpringMVC环境(同Spring环境),设定SpringMVC配置类加载对应的bean
4、初始化servlet容器,使Tomcat服务器加载SpringMVC环境,并设置SpringMVC技术处理的请求
1、使用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.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
2、创建SpringMVC控制器类(等同于servlet功能)
必须要用@Controller 来声明SpringMVC的bean
//2. 定义Controller
//2.1 使用@Controller定义bean
@Controller
public class UserController {
//2.2 设置当前操作的访问路径
@RequestMapping("/save")
//2.3 设置当前操作的返回值类型
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'username':'springmvc'}";
}
}
3、初始化SpringMVC环境(同Spring环境),设定SpringMVC配置类加载对应的bean
//3. 创建SpringMVC配置文件,加载controller对应的bean
@Configuration
@ComponentScan("com.opn.controller")
public class SpringMVCConfig {
}
4、初始化servlet容器,使Tomcat服务器加载SpringMVC环境,并设置SpringMVC技术处理的请求
//4. 定义一个servLet容器启动的配置类,在里面加裁spring 的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springMVC容器配置
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//注册springMVC配4配置类
ctx.register(SpringMVCConfig.class);
return ctx;
}
//加载spring容器配置
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
//设置哪些请求归属springMVC处理
protected String[] getServletMappings() {
//所有请求归MVC处理
return new String[]{"/"};
}
}
SpringMVC 入门注解
- @Controller
专门用来设定SpringMVC控制器
- @RequestMapping
设置当前控制器方法请求访问路径
- @ResponseBody
设置当前控制器方法响应内容为当前返回值
SpringMVC Servlet容器配置类
AbstractDispatcherServletInitializer类是SpringMVc提供的快速初始化web3.0容器的抽象类
AbstractDispatcherServletInitializer提供三个接口方法供用户实现
- createservletApplicationContext()
专门用来加载SpringMVC的核心配置
- getServletMappings()
设置请求路径
- createRootApplicationcontext()
专门用来加载Spring的核心配置
SpringMVC 开发思路
1+N
SpringMVC 入门案例工作流程分析
Bean加载控制
解决 –
Spring 加载 controller,dao,service 中的bean
springMVC 加载 controller 的bean
重复加载问题
因为功能不同,如何避免Spring错误的加载到SpringMIVC的bean
——
加载spring控制的bean的时候排除掉SpringMVC控制的bean
方式一
Spring加载bean的设定扫面范围为con.opn,排除掉controller包内的bean
方式二
Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
方式三
?
不区分Spring与SpringMVC的环境,加载到同一个环境中
方式一
先去除SpringMVC的@Configuration,
或将Spring,SpringMVC的config配置类放到com目录下
type,按照什么方式排除,此处为类型排除
class,排除@Controller注解类型的类
@Configuration
@ComponentScan(value = "com.opn",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
))
方式二
@Configuration
@ComponentScan({"com.opn.service","com.opn.dao"})
public class SpringConfig {
}
Servlet配置类简化书写
//4. 定义一个servLet容器启动的配置类,在里面加裁spring 的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springMVC容器配置
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//注册springMVC配置类
ctx.register(SpringMVCConfig.class);
return ctx;
}
//加载spring容器配置
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
//设置哪些请求归属springMVC处理
protected String[] getServletMappings() {
//所有请求归MVC处理
return new String[]{"/"};
}
}
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
PostMan工具
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件
模拟请求
get/post/ajax
简单/高效
请求与响应
设置请求映射路径
命名重复问题
团队多人开发,每人设置不同的请求路径,冲突问题如何解决
–设置规范
设置模块名作为请求路径前缀
将@RequestMapping(“/user”) 放在类上
Get/Post请求
不区分Get/Post
普通参数
+形参
@RequestMapping("/save")
@ResponseBody
public String save(String name){
return "this is name ==> "+name;
}
中文 – POST请求乱码处理
设置过滤器
在Servlet的配置类中添加过滤器
//乱码处理 -- 设置过滤器
protected Filter[] getServletFilters(){
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
五种类型参数传递
- 普通参数
- POJO类型参数
- 嵌套POJO类型参数
- 数组类型参数
- 集合类型参数
实体类需要定义get/set方法,不然无法传值
与参数访问类型无关
需要get/set方法
自动生成
fn + alt + insert
- 普通参数
普通参数: url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
- 请求参数名与形参名不同
@RequestParam
绑定请求参数与形参之间的关系
@RequestMapping("/save")
@ResponseBody
public String save(@RequestParam("name") String username, Integer age){
return "this is name ==> "+ username + "age ==> "+age;
}
请求url/save?name=123&age=123
this is name ==> 123age ==> 123
- POJO类型参数
传实体类
@RequestMapping("/usersend")
@ResponseBody
public String save2(User user){
return "this is user ==> "+ user;
}
传递的参数
url/usersend?name=123&age=123
- 嵌套POJO类型参数
带引用类型的实体类
public class Address {
public Integer id;
public String addresses;
get/set/tostring...
}
public class User {
private String name;
private Integer age;
private Address address;
get/set/tostring...
}
@RequestMapping("/save3")
@ResponseBody
public String save3(User user){
System.out.println(user);
return "this is user ==> "+ user ;
}
传递的参数
url/save3?name=123&age=333&address.id=123&address.addresses=999
传几个参数,有几个参数的值,其他参数值为null
- 数组类型参数
数组
@RequestMapping("/array")
@ResponseBody
public String array(String[] likes){
System.out.println();
return "this is ==> " + Arrays.toString(likes);
}
传递的参数
url/array?likes=p&likes=o&likes=i
- 集合类型参数
集合数据
@RequestParam 必须要加
不然会按照POJO类型处理,报错
将传入的内容作为集合的属性(如长度),而不是集合的内容
@RequestMapping("/list")
@ResponseBody
public String list(@RequestParam List<String> likes){
System.out.println();
return "this is ==> " + likes;
}
传递的参数
url/list?likes=q&likes=w&likes=e
- 普通参数
url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
请求参数名与形参变量名不同,使用@RequestParam绑定参数关系
@RequestParam
- POJO类型参数
请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
- 嵌套POJO类型参数
请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
- 数组类型参数
请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数
- 集合类型参数
请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
Python - JSON
from urllib import request
import json
# 请求体数据
request_data =["account","sign"]
headers = {"content-type": "application/json"}
req = request.Request(url="...",
headers=headers,
data=json.dumps(request_data).encode("utf-8"))
print(req.headers)
print(req.data)
reps = request.urlopen(req).read().decode("utf-8")
print(reps)
JSON数据传递
- json数组
- json对象(POJO)
- json数组(POJO)(多个实体类)
JSON 坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
@EnableWebMvc
接受外部JSON数据转对象
@EnableWebMvc
public class SpringMVCConfig {
}
- JSON数组
@RequestBody
数组
@RequestMapping("/JSON")
@ResponseBody
public String JSON(@RequestBody List<String> likes){
System.out.println();
return "this is ==> " + likes;
}
传递的参数
postman - Body - raw - JSON
["11","22","33"]
- JSON对象(POJO)
对象
@RequestMapping("/JSON2")
@ResponseBody
public String JSON2(@RequestBody User user){
System.out.println(user);
return "this is user ==> "+ user ;
}
传递的参数
postman - Body - raw - JSON
{"name":"123","age":23}
- JSON集合(POJO)(多个实体类)
多个实体类
@RequestMapping("/JSON3")
@ResponseBody
public String JSON3(@RequestBody List<User> likes){
System.out.println(likes);
return "this is ==> " + likes;
}
传递的参数
[{"name":"123","age":23},{"name":"123","age":23}]
@EnableWebMvc
@RequestBody
接收方法体中的json数据
@RequestParam 与 @RequestBody 区别
日期类型参数传递
日期类型参数
@RequestMapping("/date")
@ResponseBody
public String date(Date date,
@DateTimeFormat(pattern = "yyyy-MM-dd")Date date1,
@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")Date date2){
System.out.println(date);
System.out.println(date1);
System.out.println(date2);
return "this is ==> " + date;
}
传递的参数
/data?date=2000/01/01&date1=2000-01-01&date2=2000/01/01+01:01:01
@DateTimeFormat(pattern=””)
指定date参数类型
响应
响应界面
响应数据
@ResponseBody
- 响应页面
页面
没有@ResponseBody(作用-设置当前控制器方法响应内容为当前返回值)
@RequestMapping("/response")
public String response(){
System.out.println("跳转页面");
return "/index.jsp";
}
- 响应文本数据
文本数据
+@ResponseBody 直接返回字符串
不+@ResponseBody 程序会查询response text的文件
@RequestMapping("/response2")
@ResponseBody
public String response2(){
System.out.println("返回纯文本数据");
return "response text";
}
- 响应json对象
+@ResponseBody
@RequestMapping("/response3")
@ResponseBody
public User response3(){
System.out.println("返回json数据");
User user = new User();
user.setName("111");
user.setAge(33);
return user;
}
- 响应json对象集合
+@ResponseBody
@RequestMapping("/response4")
@ResponseBody
public List<User> response4(){
System.out.println("返回json数据集合");
User user1 = new User();
user1.setName("111");
user1.setAge(33);
User user2 = new User();
user2.setName("333");
user2.setAge(11);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
REST风格
REST简介
REST (Representational State Transfer),表现形式状态转换
隐藏资源的访问行为,无法通过地址得知对资源是何种操作
书写简化
- 访问网络资源的格式—url的格式设定
- 按照REST风格访问资源时使用行为动作区分对资源进行了何种操作
- 按照不同的请求方式,进行不同的操作
GET/POST/PUT/DELETE
上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范
描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、account ….
- 根据REST风格对资源进行访问称为RESTful
REST入门案例
- 使用实例
传参 – 在添加@RequestBody后,只能接收请求体中的json数据
postman - 选择请求方式 - Body - raw - JSON - 添加数据
{“name”:”56”}…
//查询全部
@RequestMapping(value = "/users",method = RequestMethod.GET)
@ResponseBody
public String selectall(){
return "user select ";
}
//查询单个
@RequestMapping(value = "/users/{id}",method = RequestMethod.GET)
@ResponseBody
public String selectbyid(@PathVariable Integer id){
return "user select " + id;
}
//添加
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String add(@RequestBody User user){
System.out.println(user);
return "this is user ==> "+ user;
}
//修改
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
return "user update " + user;
}
//删除
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
return "user delete " + id;
}
- 步骤
1、设定http请求动作(动词)
设置相应的method
2、设定请求参数(路径变量)
/user/{id} – 路径参数定位
@PathVariable – 从路径中取参数
- 注解
@RequestMapping
注解分析
@RequestBody
接收方法体中的json数据
@RequestParam
@PathVariable
注解分析
REST快速开发
- 路径
将方法的重复路径注解放到类的注解中
能删的删,其他保存路径参数
- @RequestBody
提到类上
- @RestController
简化,
@RestController = @Controller + @ResponseBody
- @xxxMapping
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping
再加路径变量
@GetMapping(“/{id}”)
@RestController
@RequestMapping("/users")
public class RESTController {
@GetMapping
public String selectall(){
return "user select ";
}
@GetMapping("/{id}")
public String selectbyid(@PathVariable Integer id) {
return "user select " + id;
}
}
REST案例 - 基于REST风格的数据交互
- 对于静态资源的访问
问题:
在加载前端界面时,服务器查找mapper(走了SpringMvcConfig)
解决:
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/page下的文件时,不走MVC,走page目录下的内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
在SpringMvcConfig添加搜索
@ComponentScan({"com.opn.controller","com.opn.config"})
- 步骤
先做后台功能,开发接口并调通接口
再做页面异步调用,确认功能可以正常访问
最后完成页面数据展示
补充:放行静态资源访问
- 案例代码
前端
vue
看不懂…
//添加
saveBook () {
axios.post("../books",this.formData).then((res)=>{
});
},
//主页列表查询
getAll() {
axios.get("../books").then((res)=>{
this.dataList = res.data;
});
},
后端
@RestController
@RequestMapping("/books")
public class BookController {
@PostMapping
public String save(@RequestBody Book book){
System.out.println("book save ..." + book);
return "{'model':'booksave '}" + book;
}
@GetMapping
public List<Book> getALL(){
System.out.println("success");
Book book1 = new Book();
book1.setId(1);
book1.setName("大学");
book1.setType("internet");
book1.setDescription("lll");
List<Book> list = new ArrayList<Book>();
list.add(book1);
System.out.println("book getAll ..."+list);
return list;
}
}
SSM整合 - 前后台数据交互
https://opn90.top/2023/02/13/SSM-WorkTogether/
表现层数据封装
前端接收数据格式————创建结果模型类,封装数据到data属性中
前端接收数据格式————封装操作结果到code属性中
前端接收数据格式————封装特殊消息到message(msg)属性中
{
"code":200xx,
"data":true,
"message":"数据查询失败,请重试!"
}
设置统一数据返回结果类(前后端交互)
public class Result{
private Object data;
private Integer code;
private String msg;
}
Result类中的字段并不是固定的,可以根据需要自行增减
提供若干个构造方法,方便操作
表现层与前端数据传输协议-实现
- Result类
设置统一数据返回结果类
在controller包里写…?
public class Result {
private Object data;
private Integer code;
private String msg;
get/set/tostring方法
多种构造方法,
public Result( Integer code,Object data){}
public Result(Integer code,Object data, String msg){}
}
- Code类
设置统─数据返回结果编码
在controller包里写…?
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer GET_ERR = 20040;
}
- UserController类
修改方法实现–返回值
包含多个三元运算符
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public Result save(@RequestBody User user) {
Boolean flag = userService.save(user);
return new Result(flag ? Code.SAVE_OK : Code.SAVE_ERR , flag);
}
@PutMapping
public Result update(@RequestBody User user) {
Boolean flag = userService.update(user);
return new Result(flag ? Code.UPDATE_OK : Code.UPDATE_ERR , flag);
}
@DeleteMapping("/{username}")
public Result delete(@PathVariable String username) {
Boolean flag = userService.delete(username);
return new Result(flag ? Code.DELETE_OK : Code.DELETE_ERR , flag);
}
@GetMapping("/{username}")
public Result getById(@PathVariable String username) {
User user = userService.getById(username);
Integer code = user != null ? Code.GET_OK:Code.GET_ERR;
String msg = user != null ? "查询成功":"查询失败";
return new Result(code,user,msg);
}
@GetMapping
public Result getAll() {
List<User> userlist = userService.getAll();
Integer code = userlist != null ? Code.GET_OK:Code.GET_ERR;
String msg = userlist != null ? "查询成功":"查询失败";
return new Result(code,userlist,msg);
}
}
异常处理器
- 位置
异常向上抛出
所有的异常均抛出到表现层进行处理
- 处理
分类处理,AOP思想
- 异常处理器
集中的、统一的处理项目中出现的异常
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
System.out.println(ex);
return new Result(000,null,ex.toString());
}
}
- @RestControllerAdvice注解
- @ExceptionHandler注解
项目异常处理方案
发现异常,将异常分类,业务/系统异常
其他异常,将其归如业务/系统异常中
- 补充异常编码
com.opn.controller
Code
public class Code {
public static final Integer SYSTEM_ERR = 50001;
public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
public static final Integer SYSTEM_UNKNOW_ERR = 59999;
public static final Integer BUSINESS_ERR = 60002;
//......
}
- 自定义项目系统级异常
com.opn.exception
SystemException
public class SystemException extends RuntimeException{
private Integer code;
get/set
public SystemException( Integer code,String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
- 自定义项目业务级异常
BusinessException
public class BusinessException extends RuntimeException{
private Integer code;
get/set
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
- 触发/模拟自定义异常
com.opn.service.Impl.UserService
public User getById(String username) {
if(username=="admin")
throw new BusinessException(Code.BUSINESS_ERR,"禁止查询管理员");
return userDao.getById(username);
}
- 在异常处理器中添加拦截,并处理异常
com.opn.controller.ProjectExceptionAdvice
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发
return new Result(ex.getCode(),null,ex.getMessage());
}
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
System.out.println(ex);
return new Result(ex.getCode(),null,ex.getMessage());
}
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发
return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙");
}
}
- 返回的是Result的数据
SSM整合 - 前后台通信
前后台协议联调
静态资源放行
com.opn.config.SpringMvcSupport
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
在SpringMvcConfig中添加路径
前端界面功能
仿写…看不懂
前后端数据绑定,界面数据绑定,界面操作
…
参考代码,进行修改
前端界面 - 添加、添加状态、修改、删除功能实现
https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=67
https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=68
https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=69
https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=70
拦截器
拦截器(Interceptor)
是一种动态拦截方法调用的机制,在springMC中动态拦截控制器方法的执行
作用
在指定的方法调用前后执行预先设定的代码
阻止原始方法的执行
拦截器/过滤器区别
归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对springMVc的访问进行增强
SpringMvc的访问范围
config.ServletConfig
在此处进行设置
protected String[] getServletMappings() {
return new String[]{"/"};
}
拦截器入门案例
com.opn.interceptor
ProjectInterceptor配置类
@Configuration
public class ProjectInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
配置类
com.opn.config
SpringMvcSupport/就是静态资源访问通过的类 中添加 addInterceptors 方法
配置具体的拦截路径
@Autowired
private ProjectInterceptor projectInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterceptor).addPathPatterns("/users");
}
拦截前
拦截后
在post后的操作
preHandle,true/false终止原始条件
拦截器简化开发
使用标准接口webMvcConfigurer简化开发—侵入性较强
com.opn.config
SpringMvcConfig
@Configuration
@ComponentScan({"com.opn.controller","com.opn.config","com.opn.interceptor"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterceptor).addPathPatterns("/users");
}
}
拦截器执行流程
拦截器参数
前置处理
后置处理
完成后处理
拦截器链配置
当配置多个拦截器时,形成拦截器链
执行顺序
拦截器链的运行顺序参照拦截器添加顺序为准
false
当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
当拦截器运行中断,仅运行配置在前面的拦截器的aftercompletion操作
Maven
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!