赞
踩
架构模式
(是一种软件架构设计思想
,不止Java开发中用到,其它语言也需要用到),它将应用分为三块:
M:Model(模型)
,负责业务处理及数据的收集V:View(视图)
,负责数据的展示C:Controller(控制器)
,负责调度。它是一个调度中心,它来决定什么时候调用Model来处理业务,什么时候调用View视图来展示数据MVC架构模式的描述:前端浏览器发送请求给web服务器,web服务器中的Controller接收到用户的请求,Controller负责将前端提交的数据进行封装,然后Controller调用Model来处理业务,当Model处理完业务后会返回处理之后的数据给Controller,Controller再调用View来完成数据的展示,最终将结果响应给浏览器,浏览器进行渲染展示页面。
什么是三层模型
表现层
,将Model数据模型拆封为业务层
和与数据库交互的持久层
MVC架构模式与三层模型的区别?
关注点不同
业务逻辑
组件的划分应用程序
的层次关系和分离思想MVC架构
模式的Web框架,底层基于Servlet
实现Spring MVC
Spring WebSocket
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xc</groupId>
<artifactId>springmvc-xml</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!--servletAPI-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring5和thymeleaf整合-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
组件扫描
。spring扫描这个包中的类,将这个包中的类实例化并纳入IoC容器的管理视图解析器
。视图解析器(View Resolver)的作用主要是将Controller方法返回的逻辑视图名称解析成实际的视图对象。视图解析器将解析出的视图对象返回给DispatcherServlet,并最终由DispatcherServlet将该视图对象转化为响应结果,呈现给用户<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--组件扫描-->
<context:component-scan base-package="com.xc.controller"/>
<!--视图解析器-->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集-->
<property name="characterEncoding" value="UTF-8"/>
<!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高-->
<property name="order" value="1"/>
<!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板-->
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析-->
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!--设置模板文件的位置(前缀)-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--设置模板文件后缀(后缀),Thymeleaf文件扩展名不一定是html,也可以是其他,例如txt,大部分都是html-->
<property name="suffix" value=".html"/>
<!--设置模板类型,例如:HTML,TEXT,JAVASCRIPT,CSS等-->
<property name="templateMode" value="HTML"/>
<!--用于模板文件在读取和解析过程中采用的编码字符集-->
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
Servlet
DispatcherServlet
,我们称其为前端控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<!--配置前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--手动设置springmvc配置文件的路径及名字-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--为了提高用户的第一次访问效率,建议在web服务器启动时初始化前端控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- /* 表示任何一个请求都交给DispatcherServlet来处理 -->
<!-- / 表示当请求不是xx.jsp的时候,DispatcherServlet来负责处理本次请求-->
<!-- jsp本质就是Servlet,因此如果请求是jsp的话,应该走它自己的Servlet,而不应该走DispatcherServlet -->
<!-- 因此我们的 url-pattern 使用 / -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
DispatcherServlet是SpringMVC框架为我们提供的最核心的类,它是整个SpringMVC框架的前端控制器,负责接收HTTP请求、将请求路由到处理程序
、处理响应信息
,最终将响应返回给客户端。
控制器(Controller)
来处理此请求模型对象(Model)
HTML页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello world
</body>
</html>
@Controller
public class HelloController {
@RequestMapping("/test")
public String test(){
return "success";
}
}
配置Tomcat
启动tomcat,调用test
@RequestMapping
注解是 Spring MVC 框架中的一个控制器映射注解
,用于将请求映射到相应的处理方法上。具体来说,它可以将指定 URL 的请求绑定到一个特定的方法或类上,从而实现对请求的处理和响应。
RequestMapping的出现位置
类上
或者方法上
请求路径
,也就是说通过该请求路径与对应的控制器的方法绑定在一起数组
,表示可以提供多个路径
,也就是说,多个不同的请求路径可以映射同一个控制器的同一个方法value
属性和path
属性互为别名,两个属性一样举例
@Controller
@RequestMapping("/hello")
public class RequestMappingController {
@RequestMapping(value = {"/test1","test2"})
public String test(){
return "success";
}
}
模糊匹配
,我们把这种模糊匹配称之为Ant风格
?
:表示任意的单个字符*
:表示任意的0个或多个字符**
:表示任意的一层或多层目录(只能使用xxx/**
的方式)匹配?例子
@RequestMapping("/x?z/testValueAnt")
public String testValueAnt(){
return "success";
}
匹配*例子
@RequestMapping("/x*z/testValueAnt")
public String testValueAnt(){
return "success";
}
匹配**例子
**
通配符只能出现在路径的末尾
,否则抛错,spring5可以不用在末尾@RequestMapping("/testValueAnt/**")
public String testValueAnt(){
return "success";
}
普通的请求路径:http://localhost:8080/springmvc/login?username=admin&password=123&age=20
restful风格的请求路径:http://localhost:8080/springmvc/login/admin/123/20
如果使用restful风格的请求路径,在控制器中应该如何获取请求中的数据呢?
@PathVariable
路径变量注解会抛500异常@RequestMapping(value = "/testRestful/{id}/{username}/{age}")
public String testRestful(
@PathVariable("id") int id,
@PathVariable("username") String username,
@PathVariable("age") int age) {
System.out.println(id + "," + username + "," + age);
return "success";
}
405
错误RequestMapping注解
的method
属性来实现限制请求方式
数组
RequestMethod
,而RequestMethod是一个枚举
类型的数据举例
@RequestMapping(value="/login", method = {RequestMethod.GET,RequestMethod.POST})
public String testMethod(){
return "success";
}
GetMapping
:要求前端必须发送get请求PutMapping
:要求前端必须发送put请求DeleteMapping
:要求前端必须发送delete请求PatchMapping
:要求前端必须发送patch请求举例
//@RequestMapping(value="/login", method = RequestMethod.POST)
@PostMapping("/login")
public String testMethod(){
return "success";
}
前端向服务器发送请求的方式包括哪些?共9种
获取资源
,只允许读取数据,不影响数据的状态和功能
URL中传递参数
或者在HTTP请求的头部使用参数
,服务器返回请求的资源提交资源
,可能还会改变数据的状态和功能
请求体
,服务器接收请求体后,进行数据处理更新资源
,用于更新指定的资源上所有可编辑内容
请求体
发送需要被更新的全部内容,服务器接收数据后,将被更新的资源进行替换或修改删除资源
,用于删除指定的资源
URL中或请求体
中跨域检查
⚠️注意
ajax
请求的方式来实现GET和POST的区别
获取数据
传送数据
支持缓存
。 也就是说当第二次发送get请求时,会走浏览器上次的缓存结果,不再真正的请求服务器不支持缓存
。每一次发送post请求都会真正的走服务器数组
,不过要求请求参数必须和params数组中要求的所有参数完全一致
后,才能映射成功params属性的4种用法
@RequestMapping(value="/login", params={"username", "password"})
@RequestMapping(value="/login", params={"!username", "password"})
@RequestMapping(value="/login", params={"username=admin", "password"})
@RequestMapping(value="/login", params={"username!=admin", "password"})
请求头信息一致
时,才能映射成功headers属性的4种用法
@RequestMapping(value="/login", headers={"Referer", "Host"})
@RequestMapping(value="/login", headers={"!Referer", "Host"})
@RequestMapping(value="/login", headers={"Referer=xxx", "Host"})
@RequestMapping(value="/login", headers={"Referer!=xxx", "Host"})
前端表单提交数据
F12查询提交数据方式
后端控制器获取数据
@PostMapping(value="/register")
public String register(HttpServletRequest request){
// 通过当前请求对象获取提交的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String sex = request.getParameter("sex");
String[] hobbies = request.getParameterValues("hobby");
String intro = request.getParameter("intro");
System.out.println(username + "," + password +
"," + sex + "," + Arrays.toString(hobbies) + "," + intro);
return "success";
}
这样通过Servlet原生的API获取到提交的数据。但是这种方式不建议使用
,因为方法的参数HttpServletRequest
依赖Servlet原生API,Controller的测试将不能单独测试,必须依赖web服务器
才能测试。
请求参数
与方法上的形参
映射@PostMapping(value = "/register")
public String register(
@RequestParam(value = "username") String a,
@RequestParam(value = "password") String b,
@RequestParam(value = "sex") String c,
@RequestParam(value = "hobby") String[] d,
@RequestParam(name = "intro") String e
) {
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(Arrays.toString(d));
System.out.println(e);
return "success";
}
value
和name
,互为别名
,作用相同name1=value1&name2=value2
,则这个注解应该这样写:@RequestParam(value="name1")
、@RequestParam(value="name2")
是否为必须
的true
,表示方法参数是必需的。如果请求中缺少对应的参数,则会抛出异常false
,false表示不是必须的,如果请求中缺少对应的参数,则方法的参数为null举例
没有提供对应的请求参数
或者请求参数的值是空字符串""
的时候,方法的形参会采用默认值举例
方法形参的名字
和提交数据时的name相同,则@RequestParam可以省略@PostMapping(value="/register")
public String register(String username, String password, String sex,
String[] hobby, String intro){
System.out.println(username + "," + password + "," + sex + ","
+ Arrays.toString(hobby) + "," + intro);
return "success";
}
实体类
来接收请求参数实体类的属性名
必须和请求参数的参数名
保持一致@PostMapping("/register")
public String register(User user){
System.out.println(user);
return "success";
}
setter方法名
请求头信息
映射到方法的形参上
@PostMapping("/register")
public String register(User user,
@RequestHeader(value="Referer", required = false, defaultValue = "") String referer){
System.out.println(user);
System.out.println(referer);
return "success";
}
请求提交的Cookie数据
映射到方法的形参上
@GetMapping("/register")
public String register(User user,
@CookieValue(value="id", required = false, defaultValue = "110") String id){
System.out.println(user);
System.out.println(id);
return "success";
}
server.xml
文件,找到其中配置端口号的标签<Connector>
,在该标签中添加URIEncoding="UTF-8
Tomcat10
,Tomcat9
,有如下的默认配置,在默认情况下URIEncoding使用的就是UTF-8的编码方式Tomcat8
,URIEncoding的默认配置是ISO-8859-1
请求体
的中文乱码问题request.setCharacterEncoding("UTF-8");
Tomcat10
服务器来说,针对请求体中的字符编码也是配置好的,默认也是采用了UTF-8,web.xml
配置如下乱码过滤器
<!--配置SpringMVC自带的乱码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<!--
设置forceEncoding为true,就是强制设置编码的意思
forceEncoding为true就会设置forceRequestEncoding和forceResponseEncoding为true
这样,如下源码的两个if条件成立,就会设置utf-8编码了
-->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
request
、会话域:session
、应用域:application
// 向域中存储数据
void setAttribute(String name, Object obj);
// 从域中读取数据
Object getAttribute(String name);
// 删除域中的数据
void removeAttribute(String name);
数据的传递和共享
一次请求
,一次请求一个request使用原生Servlet API方式
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
// 向request域中存储数据
request.setAttribute("testRequestScope", "在SpringMVC中使用原生Servlet API实现request域数据共享");
return "view";
}
使用Model接口
@RequestMapping("/testModel")
public String testModel(Model model){
// 向request域中存储数据
model.addAttribute("testRequestScope", "在SpringMVC中使用Model接口实现request域数据共享");
return "view";
}
使用Map接口
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
// 向request域中存储数据
map.put("testRequestScope", "在SpringMVC中使用Map接口实现request域数据共享");
return "view";
}
使用ModelMap类
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
// 向request域中存储数据
modelMap.addAttribute("testRequestScope", "在SpringMVC中使用ModelMap实现request域数据共享");
return "view";
}
Model、Map、ModelMap的关系?
BindingAwareModelMap
ModelMap
实现Model
,而ModelMap又实现了Map
接口使用ModelAndView类
ModelAndView
。这个类的实例封装了Model
和View
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
// 创建“模型与视图对象”
ModelAndView modelAndView = new ModelAndView();
// 绑定数据
modelAndView.addObject("testRequestScope", "在SpringMVC中使用ModelAndView实现request域数据共享");
// 绑定视图
modelAndView.setViewName("view");
// 返回
return modelAndView;
}
注意:
以上我们通过了五种方式完成了request域数据共享,这几种方式在底层DispatcherServlet调用我们的Controller之后,返回的对象都是ModelAndView
。
使用原生Servlet API方式
@RequestMapping("/testSessionScope1")
public String testServletAPI(HttpSession session) {
// 向会话域中存储数据
session.setAttribute("testSessionScope1", "使用原生Servlet API实现session域共享数据");
return "view";
}
使用原生Servlet API方式
@RequestMapping("/testApplicationScope")
public String testApplicationScope(HttpServletRequest request){
// 获取ServletContext对象
ServletContext application = request.getServletContext();
// 向应用域中存储数据
application.setAttribute("applicationScope", "我是应用域当中的一条数据");
return "view";
}
HttpMessageConverter
是Spring MVC中非常重要的一个接口
HTTP消息转换器
。该接口下提供了很多实现类,不同的实现类有不同的转换方式HTTP协议
与Java程序中的对象
之间的互相转换Form表单转换器
请求体中的数据是如何转换成user对象的,底层实际上使用了HttpMessageConverter
接口的其中一个实现类FormHttpMessageConverter
。
通过上图可以看出FormHttpMessageConverter
是负责将请求协议
转换为Java对象
的。
默认转换器
Controller返回值看做逻辑视图名称,视图解析器将其转换成物理视图名称,生成视图对象,StringHttpMessageConverter
负责将视图对象中的HTML字符串写入到HTTP协议的响应体中。最终完成响应。
通过上图可以看出StringHttpMessageConverter
是负责将Java对象
转换为响应协议
的。
首页面AJAX请求获取数据,非跳转页面Controller
// 有返回值
@RequestMapping(value = "/hello1")
public String hello1(HttpServletResponse response) throws IOException {
response.getWriter().print("hello");
return null;
}
// 无返回值
@RequestMapping(value = "/hello2")
public void hello2(HttpServletResponse response) throws IOException {
response.getWriter().print("hello");
}
页面展示
注意:如果采用这种方式响应,则和 springmvc.xml 文件中配置的视图解析器没有关系,不走视图解析器了
StringHttpMessageConverter
,为什么会启用这个消息转换器呢?
@ResponseBody
这个注解@Controller
public class HelloController {
@RequestMapping(value = "/hello")
@ResponseBody
public String hello(){
// 由于你使用了 @ResponseBody 注解
// 以下的return语句返回的字符串则不再是“逻辑视图名”了
// 而是作为响应协议的响应体进行响应。
return "hello";
}
}
JSON格式的字符串
,可以返回JSON格式的字符串吗?当然可以,代码如下:@Controller
public class HelloController {
@RequestMapping(value = "/hello")
@ResponseBody
public String hello(){
return "{\"username\":\"zhangsan\",\"password\":\"1234\"}";
}
}
页面展示
StringHttpMessageConverter
POJO对象
,怎么将POJO对象以JSON格式的字符串响应给浏览器呢?
MappingJackson2HttpMessageConverter
消息转换器启动JSON消息转换器需要两个步骤
jackson依赖
,可以将java对象转换为json格式字符串<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
注解驱动
,会自动装配一个消息转换器:MappingJackson2HttpMessageConverter<mvc:annotation-driven/>
@ResponseBody最经典用法如下:
@RequestMapping(value = "/hello")
@ResponseBody
public User hello(){
User user = new User("zhangsan", "18");
return user;
}
@RestController
。这一个注解代表了:@Controller + @ResponseBody
所有的方法
上都会自动标注@ResponseBody@RestController
public class HelloController {
@RequestMapping(value = "/hello")
public User hello(){
User user = new User("zhangsan", "18");
return user;
}
}
在没有使用这个注解的时候:
@RequestMapping("/save")
public String save(User user){
// 执行保存的业务逻辑
userDao.save(user);
// 保存成功跳转到成功页面
return "success";
}
当请求体
提交的数据是:
username=zhangsan&password=1234&email=zhangsan@powernode.com
那么Spring MVC会自动使用 FormHttpMessageConverter
消息转换器,将请求体转换成user对象
当使用这个注解的时候:这个注解只能出现在
方法的参数上
@RequestMapping("/save")
public String save(@RequestBody String requestBodyStr){
System.out.println("请求体:" + requestBodyStr);
return "success";
}
Spring MVC仍然会使用 FormHttpMessageConverter
消息转换器,将请求体直接以字符串形式传递给requestBodyStr变量
请求体
是JSON
格式字符串,可以将其转化为POJO对象MappingJackson2HttpMessageConverter
jackson依赖
、开启注解驱动
@RequestMapping("/send")
@ResponseBody
public String send(@RequestBody User user){
System.out.println(user);
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return "success";
}
请求行
、请求头
、请求体
所有信息@RequestMapping("/send")
@ResponseBody
public String send(RequestEntity<User> requestEntity){
System.out.println("请求方式:" + requestEntity.getMethod());
System.out.println("请求URL:" + requestEntity.getUrl());
HttpHeaders headers = requestEntity.getHeaders();
System.out.println("请求的内容类型:" + headers.getContentType());
System.out.println("请求头:" + headers);
User user = requestEntity.getBody();
System.out.println(user);
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return "success";
}
执行结果:
状态行
、响应头
、响应体
@Controller
public class UserController {
@GetMapping("/users/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.getUserById(id);
if (user == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
} else {
return ResponseEntity.ok(user);
}
}
}
异常
,跳转到对应的视图
,在视图上展示友好信息默认处理器DefaultHandlerExceptionResolver
核心方法:
当请求方式和处理方式不同
时,DefaultHandlerExceptionResolver的默认处理态度是:
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler
public String exceptionHandler(Exception e, Model model){
model.addAttribute("e", e);
return "error";
}
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>出错了</title>
</head>
<body>
<h1>出错了,请联系管理员!</h1>
<div th:text="${e}"></div>
</body>
</html>
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = {Exception.class})
@ResponseBody
public ResponseEntity<String> exceptionHandler(Exception e, Model model) {
// 这里先判断拦截到的Exceptiion是不是我们自定义的异常类型
if (e instanceof MyException) {
MyException myException = (MyException) e;
return ResponseEntity.status(500).body(myException.getMeg());
} else {
// 如果拦截的异常不是我们自定义的异常(例如:数据库主键冲突)
return ResponseEntity.status(500).body("服务器端异常");
}
}
}
请求到达控制器之前或之后进行拦截
,可以对请求和响应进行一些特定的处理登录验证
:对于需要登录才能访问的网址,使用拦截器可以判断用户是否已登录,如果未登录则跳转到登录页面权限校验
:根据用户权限对部分网址进行访问控制,拒绝未经授权的用户访问请求日志
:记录请求信息,例如请求地址、请求参数、请求时间等,用于排查问题和性能优化更改响应
:可以对响应的内容进行修改,例如添加头信息、调整响应内容格式等请求和响应
的流程中进行处理,可以修改请求和响应的内容,例如设置编码和字符集、请求头、状态码等控制器
进行前置或后置处理,在请求到达控制器之前或之后进行特定的操作,例如打印日志、权限验证等Filter、Servlet、Interceptor、Controller的执行顺序:
定义拦截器
org.springframework.web.servlet.HandlerInterceptor
接口,共有三个方法可以进行选择性的实现
preHandle
:处理器方法调用之前执行(返回true放行,false拦截)postHandle
:处理器方法调用之后执行afterCompletion
:渲染完成后执行(无论是否抛异常最终必会执行)@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("处理器方法前调用");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("处理器方法后调用");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("渲染完成后调用");
}
}
基本配置
springmvc.xml配置如下
<mvc:interceptors>
<bean class="com.xc.interceptors.MyInterceptor"/>
</mvc:interceptors>
<!-- 或者 -->
<mvc:interceptors>
<ref bean="myInterceptor"/>
</mvc:interceptors>
添加组件扫描
注意:对于这种基本配置来说,拦截器是拦截所有请求的
如果所有拦截器preHandle都返回true
按照springmvc.xml文件中配置的顺序,自上而下
调用 preHandle
<mvc:interceptors>
<ref bean="interceptor1"/>
<ref bean="interceptor2"/>
</mvc:interceptors>
执行顺序:
如果其中一个拦截器preHandle返回false
<mvc:interceptors>
<ref bean="interceptor1"/>
<ref bean="interceptor2"/>
</mvc:interceptors>
如果interceptor2
的preHandle返回false,执行顺序:
规则:只要有一个拦截器preHandle
返回false,所有postHandle
都不执行。但返回false的拦截器的前面的拦截器按照逆序执行afterCompletion
。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。