前言
SpringMVC学习笔记
利用Maven创建Web项目
添加依赖
pom.xml
1 2 3 4 5 6 7 8 9 10 11
| <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>
|
定义Controller类
src/main/java/com/controller/UserController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;
@Controller public class UserController {
@RequestMapping("/method") @ResponseBody public String method() { return "{'key':'value'}"; } }
|
创建SpringMVC容器配置类
- 将Controller类交给SpringMVC容器管理
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8 9
| package com.conf;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;
@Configuration @ComponentScan("com.controller") public class SpringMvcConfig { }
|
创建Servlet配置类
继承子类(用于简化开发)
- 创建Servlet配置类,继承AbstractAnnotationConfigDispatcherServletInitializer类,加载SpringMVC的配置类
src/main/java/com/conf/ServletContainersInitConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.conf;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
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[]{"/"}; } }
|
继承父类(用于学习底层)
- 创建Servlet配置类,继承AbstractDispatcherServletInitializer类,加载SpringMVC的配置类
src/main/java/com/conf/ServletContainersInitConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.conf;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(SpringMvcConfig.class); return applicationContext; }
protected String[] getServletMappings() { return new String[]{"/"}; }
protected WebApplicationContext createRootApplicationContext() { return null; } }
|
放行静态页面访问请求
创建SpringMvcSupport配置类
- 继承
WebMvcConfigurationSupport
类,重写addResourceHandlers()
方法和addInterceptors()
方法
addResourceHandler("/pages/**", "/pages/")
:当访问的资源路径为/pages/**
时,访问静态路径/pages/
下的资源
src/main/java/com/conf/SpringMvcSupport.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.conf;
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**", "/pages/"); registry.addResourceHandler("/css/**", "/pages/"); registry.addResourceHandler("/js/**", "/pages/"); } }
|
在SpringMVC容器配置类添加包扫描范围
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8 9 10
| package com.conf;
import org.springframework.context.annotation.ComponentScan; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration @ComponentScan({"com.controller", "com.conf"}) @EnableWebMvc public class SpringMvcConfig { }
|
与Spring容器整合
创建Spring容器配置类
- 因为Controller类已经交给了SpringMVC容器管理,所以在Spring容器配置类中排除对Controller的bean管理
@ComponentScan()
:指定包扫描
value = ""
:指定扫描的包
excludeFilters = @ComponentScan.Filter()
:指定排除过滤器
type
:过滤器类型
FilterType.ANNOTATION
:根据注解过滤
FilterType.REGEX
:根据正则表达式过滤
FilterType.CUSTOM
:根据用户自定义方式过滤
classes
:如果过滤类型是根据注解过滤,可以通过classes指定过滤的注解类型
src/main/java/com/conf/SpringConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.conf;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller;
@Configuration @ComponentScan( value = "com", excludeFilters = @ComponentScan.Filter( type = FilterType.ANNOTATION, classes = Controller.class ) ) public class SpringConfig {
}
|
不将SpringMvcConfig类作为配置类
- 因为Controller已经交给了SpringMVC容器管理,为了防止Spring容再次管理Controller,需要注释SpringMVC容器配置类中的
@Configuration
注解
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8
| package com.conf;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("com.controller") public class SpringMvcConfig { }
|
让tomcat服务器启动时加载Spring容器
src/main/java/com/conf/ServletContainersInitConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.conf;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(SpringMvcConfig.class); return applicationContext; }
protected String[] getServletMappings() { return new String[]{"/"}; }
protected WebApplicationContext createRootApplicationContext() { AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(SpringConfig.class); return applicationContext; } }
|
过滤器
解决POST请求的中文乱码
- 在Servlet配置类中添加
getServletFilters()
过滤器配置方法,利用过滤器解决POST请求的中文乱码
src/main/java/com/conf/ServletContainersInitConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.conf;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
import javax.servlet.Filter;
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(SpringMvcConfig.class); return applicationContext; }
protected String[] getServletMappings() { return new String[]{"/"}; }
protected WebApplicationContext createRootApplicationContext() { AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(SpringConfig.class); return applicationContext; }
@Override protected Filter[] getServletFilters() { CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF-8"); return new Filter[]{characterEncodingFilter}; } }
|
开启JSON请求转换对象接收
- 在SpringMVC配置类上添加
@EnableWebMvc
注解
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8 9
| package com.conf;
import org.springframework.context.annotation.ComponentScan; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@ComponentScan("com.controller") @EnableWebMvc public class SpringMvcConfig { }
|
请求
@RequestParam
:用于处理application/x-www-form-urlencoded
表单传参
@RequestBody
:用于处理application/json
请求体json格式传参
GET请求
基本类型请求参数
- 请求参数名与形参名相同时,可以自动进行映射;请求参数名与形参名不同时,需要手动进行映射
- 形参指定多个用于接收多个请求参数,形参顺序可以与请求参数传递的顺序不同
@RequestParam("")
:指定请求中的参数名,如果请求参数名与形参名相同,可以省略
value = ""
:指定请求参数名
required = true
:是否为必传的参数
defaultValue = ""
:指定参数默认值
1 2 3 4 5
| @RequestMapping("/") public String method(@RequestParam("") int id, String name) { ... return ""; }
|
引用类型请求参数
- 首先定义一个实体类,实体类中的属性名与请求参数名保持相同,并定义相关get、set、toString方法
src/main/java/com/pojo/User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.pojo;
public class User { Integer id; String name;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
1 2 3 4 5
| @RequestMapping("/") public String method(User user) { ... return ""; }
|
数组请求参数
- 当相同参数名的请求值有多个的时候,可以使用数组进行接收
- 也可以使用字符串类型强制接收所有参数值,默认使用逗号分隔
1 2 3 4 5
| @RequestMapping("/") public String method(String[] name) { ... return ""; }
|
集合类型请求参数
- 当相同参数名的请求值有多个的时候,可以使用集合进行接收
- 接收集合类型的请求时,必须要添加
@RequestParam
注解
1 2 3 4 5
| @RequestMapping("/") public String method(@RequestParam List<String> name) { ... return ""; }
|
日期类型请求参数
1 2 3 4 5 6
| @RequestMapping("/") public String method(Date date) { System.out.println(date.toLocaleString()); ... return ""; }
|
重新指定日期格式化方式
1 2 3 4 5 6
| @RequestMapping("/") public String method(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date) { System.out.println(date.toLocaleString()); ... return ""; }
|
重新指定所有日期格式化方式
- 添加SpringMVC自定义日期格式转换器,将SpringMVC默认以
/
分隔改为以-
分隔
1 2 3 4
| @InitBinder public void InitBinder (ServletRequestDataBinder binder) { binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true)); }
|
POST请求
引用类型请求参数
- 首先定义一个实体类,实体类中的属性名与请求参数名保持相同,并定义相关get、set、toString方法
- 因为POST请求的参数在请求体中传递,所以必须添加
@RequestBody
注解
src/main/java/com/pojo/User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.pojo;
public class User { Integer id; String name;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
1 2 3 4 5
| @RequestMapping("/") public String method(@RequestBody User user) { ... return ""; }
|
集合类型请求参数
- 当请求参数为JSON格式的数组时,可以使用集合进行接收
- 需要先开启JSON请求转换对象接收
- 因为POST请求的参数在请求体中传递,所以必须添加
@RequestBody
注解
1 2 3 4 5
| @RequestMapping("/") public String method(@RequestBody List<String> name) { ... return ""; }
|
REST风格请求
- REST(Representational State Transfer):表现形式状态转换
- 风格表示建议,而不是规范,不强制遵照要求
- REST风格的请求在访问模块时要以s结尾
- RESTful:根据REST风格对资源进行访问访问
请求方式 |
请求路径 |
执行操作 |
GET |
http://localhost/users |
查询全部信息 |
GET |
http://localhost/users/1 |
查询指定信息 |
POST |
http://localhost/users |
添加信息 |
PUT |
http://localhost/users |
修改信息 |
DELETE |
http://localhost/users/1 |
删除指定信息 |
快速入门
@PathVariable
:在请求路径传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package com.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody;
@Controller @ResponseBody @RequestMapping("/users") public class UserController {
@RequestMapping(method = RequestMethod.GET) public String getUsers() { return "getUsers()"; }
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public String getUserById(@PathVariable int id) { return "getUserById()"; }
@RequestMapping(method = RequestMethod.POST) public String insertUser() { return "insertUser()"; }
@RequestMapping(method = RequestMethod.PUT) public String updateUser() { return "updateUser()"; }
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE) public String deleteUserById(@PathVariable int id) { return "deleteUserById()"; } }
|
简化
- 用
@RestController
替换@Controller
和@ResponseBody
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package com.controller;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@RestController @RequestMapping("/users") public class UserController {
@GetMapping public String getUsers() { return "getUsers()"; }
@GetMapping("/{id}") public String getUserById(@PathVariable int id) { return "getUserById()"; }
@PostMapping public String insertUser() { return "insertUser()"; }
@PutMapping public String updateUser() { return "updateUser()"; }
@DeleteMapping("/{id}") public String deleteUserById(@PathVariable int id) { return "deleteUserById()"; } }
|
响应
只跳转页面
- 以后我们写代码可以单独写
TemplatePageController
用于处理页面跳转
配置前端页面访问路径的前后缀
1 2
| spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html
|
返回字符串(常用)
- 通过返回的字符串(string),根据prefix+string+suffix进行页面跳转
1 2 3 4 5
| @RequestMapping("/") public String method() { ... return ""; }
|
转发和重定向
转发到本项目
1 2 3 4 5
| @RequestMapping("/") public String method() { ... return "index"; }
|
转发到其他位置
1 2 3 4 5
| @RequestMapping("/") public String method() { ... return "forward:/index"; }
|
目标重定向
重定向到站内
- 在SpringMVC中目标重定向也可以通过Model传递参数
- 返回值加
redirect:
前缀
1 2 3 4 5
| @RequestMapping("/") public String method() { ... return "redirect:/test"; }
|
重定向到站外
1 2 3 4 5
| @RequestMapping("/") public String method() { ... return "redirect:/http://localhost:8080/"; }
|
只响应数据
返回Map对象(常用)
1 2 3 4 5 6 7
| @RequestMapping("/") @ResponseBody public Map<String, Object> method() { Map<String, Object> map = new HashMap<>(); map.put(<key>, <value>); return map; }
|
返回引用类型对象
src/main/java/com/pojo/User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.pojo;
public class User { Integer id; String name;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
1 2 3 4 5 6 7 8
| @RequestMapping("/") @ResponseBody public User method() { User user = new User(); user.setId(1); user.setName(""); return user; }
|
返回值为空
- 将数据存储在Map对象,将Map对象转换为json格式字符串
- 通过HttpServletResponse对象,响应数据到客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @RequestMapping("/") public void method(HttpServletResponse response) throws Exception { Map<String, Object> map = new HashMap<>(); map.put(<key>, <value>); ObjectMapper objectMapper = new ObjectMapper(); String jsonStr = objectMapper.writeValueAsString(map); response.setContentType("text/html;charset=utf-8"); response.getWriter().println(jsonStr); }
|
既响应数据,又跳转页面
- 以后我们写代码可以单独写
ModelAndViewController
用于同时页面跳转并响应数据
返回ModelAndView对象(常用)
- 返回值会交给DispatcherServletd对象进行处理
- DispatcherServlet对象会调用viewresolver对结果进行解析
- 基于viewresolver找到对应的view页面(prefix+viewname+suffix)
- 将model中的数据填充到view页面上
- 返回一个带有model数据的页面给DispatcherServlet
- DispatcherServlet将带有model数据的页面响应到客户端
1 2 3 4 5 6 7
| @RequestMapping("/") public ModelAndView method() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName(""); modelAndView.addObject(<key>, <value>); return modelAndView; }
|
返回字符串
- 通过Model对象传输数据,将数据填充到页面上
- 通过返回的字符串(string),根据prefix+string+suffix进行页面跳转
<key>
:键,仅可以字符串类型
<value>
:值,可以任意类型
1 2 3 4 5 6
| @RequestMapping("/") public String method(Model model) { model.addAttribute(<key>, <value>); ... return ""; }
|
拦截器
- 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
- 作用
- 在指定的方法调用前后执行预先设定的代码
- 终止原始方法的执行
- 拦截器与过滤器的区别
- 归属不同:拦截器属于SpringMVC的技术,过滤器属于Servlet的技术
- 拦截内容不同:拦截器仅对SpringMVC进行增强,过滤器对所有访问进行增强
创建拦截器类
- 如果
preHandle()
方法返回false
,表示拦截,则原始操作及其之后的操作都不执行
- 如果
preHandle()
方法返回true
,表示放行,则原始操作及其之后的操作都正常执行
- 形参
handler
可以通过反射获取原始操作的对象
src/main/java/com/controller/interceptor/UserInterceptor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.controller.interceptor;
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
@Component public class UserInterceptor 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()"); } }
|
配置类
通过SpringMvcSupport配置类完成配置
创建SpringMvcSupport配置类
- 继承
WebMvcConfigurationSupport
类,重写addResourceHandlers()
方法和addInterceptors()
方法
- 通过
addResourceHandlers()
方法配置放行的请求范围
- 通过
addInterceptors()
方法配置拦截器及其管理的请求范围
addResourceHandler("/pages/**", "/pages/")
:当访问的资源路径为/pages/**
时,访问静态路径/pages/
下的资源
src/main/java/com/conf/SpringMvcSupport.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.conf;
import com.interceptor.UserInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Autowired private UserInterceptor userInterceptor;
@Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); }
@Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor).addPathPatterns("/users", "/users/*); } }
|
在SpringMVC容器配置类添加包扫描范围
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8 9 10
| package com.conf;
import org.springframework.context.annotation.ComponentScan; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration @ComponentScan({"com.controller", "com.interceptor", "com.conf"}) @EnableWebMvc public class SpringMvcConfig { }
|
直接通过SpringMvcConfig配置类完成配置(简化)
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.conf;
import com.controller.interceptor.UserInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @ComponentScan({"com.controller"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired private UserInterceptor userInterceptor;
public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor).addPathPatterns("/user", "/users/*"); } }
|
拦截器链
创建多个拦截器类
src/main/java/com/controller/interceptor/UserInterceptor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.controller.interceptor;
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
@Component public class UserInterceptor 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()"); } }
|
src/main/java/com/controller/interceptor/UserInterceptor2.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.controller.interceptor;
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
@Component public class UserInterceptor2 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()"); } }
|
引入多个配置
src/main/java/com/conf/SpringMvcConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.conf;
import com.controller.interceptor.UserInterceptor; import com.controller.interceptor.UserInterceptor2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @ComponentScan({"com.controller"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired private UserInterceptor userInterceptor;
@Autowired private UserInterceptor2 userInterceptor2; public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor).addPathPatterns("/user", "/users/*"); registry.addInterceptor(userInterceptor2).addPathPatterns("/user", "/users/*"); } }
|
拦截器的执行顺序
- 拦截器执行顺序根据
addInterceptors()
方法配置拦截器的顺序而排序
拦截器的执行顺序
当preHandle()返回true时
- 拦截器的
preHandle()
-> 原始操作 -> 拦截器的postHandle()
-> 拦截器的afterCompletion()
-> 运行结束
当preHandle()返回false时
拦截器链的执行顺序
当preHandle()返回true时
- 拦截器1的
preHandle()
-> 拦截器2的preHandle()
-> 拦截器3的preHandle()
-> 原始操作 -> 拦截器3的postHandle()
-> 拦截器2的postHandle()
-> 拦截器1的postHandle()
-> 拦截器3的afterCompletion()
-> 拦截器2的afterCompletion()
-> 拦截器1的afterCompletion()
-> 运行结束
当userInterceptor3的preHandle()返回false时
- 拦截器1的
preHandle()
-> 拦截器2的preHandle()
-> 拦截器3的preHandle()
-> 拦截器2的afterCompletion()
-> 拦截器1的afterCompletion()
-> 运行结束
完成
参考文献
哔哩哔哩——黑马程序员