SpringMVC Reference
SpringMVC 简介
MVC 模式
MVC 是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的开发思想。
1* M(model)模型:处理业务逻辑,封装实体
2* V(view) 视图:展示内容
3* C(controller)控制器:负责调度分发(1.接收请求、2.调用模型、3.转发到视图)
SpringMVC 概述
SpringMVC 是一种基于 Java 的实现 MVC 设计模式的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。
SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTFul 编程风格的请求。
SpringMVC 的框架就是封装了原来 Servlet 中的共有行为;例如:参数封装,视图转发等。
快速上手
客户端发起请求,服务器接收请求,执行逻辑并进行视图跳转
- 创建 Web 项目,导入 SpringMVC 相关坐标
- 配置 SpringMVC 前端控制器 DispathcerServlet
- 编写 Controller 类和视图页面
- 使用注解配置 Controller 类中业务方法的映射地址
- 配置 SpringMVC 核心文件 spring-mvc.xml
- 创建 Web 项目,导入 SpringMVC 相关坐标
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>com.soulboy</groupId>
8 <artifactId>springmvc_quickstart</artifactId>
9 <version>1.0-SNAPSHOT</version>
10
11 <!--指定编码及版本-->
12 <properties>
13 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14 <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
15 <java.version>1.11</java.version>
16 <maven.compiler.source>1.11</maven.compiler.source>
17 <maven.compiler.target>1.11</maven.compiler.target>
18 </properties>
19
20 <!-- 打包方式 -->
21 <packaging>war</packaging>
22
23 <dependencies>
24 <!--springMVC坐标-->
25 <dependency>
26 <groupId>org.springframework</groupId>
27 <artifactId>spring-webmvc</artifactId>
28 <version>5.1.5.RELEASE</version>
29 </dependency>
30 <!--servlet坐标-->
31 <dependency>
32 <groupId>javax.servlet</groupId>
33 <artifactId>javax.servlet-api</artifactId>
34 <version>3.1.0</version>
35 <scope>provided</scope>
36 </dependency>
37 <!--jsp坐标-->
38 <dependency>
39 <groupId>javax.servlet.jsp</groupId>
40 <artifactId>jsp-api</artifactId>
41 <version>2.2</version>
42 <scope>provided</scope>
43 </dependency>
44 </dependencies>
45
46</project>
1.1 创建 webapp 目录
- 配置 SpringMVC 前端控制器 DispathcerServlet
src/main/webapp/WEB-INF/web.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
5 version="4.0">
6
7 <!--前端控制器-->
8 <servlet>
9 <servlet-name>dispatcherServlet</servlet-name>
10 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
11 <init-param>
12 <param-name>contextConfigLocation</param-name>
13 <param-value>classpath:spring-mvc.xml</param-value>
14 </init-param>
15 <!-- 在程序启动时候实例化servlet实例化初始化操作 -->
16 <load-on-startup>2</load-on-startup>
17 </servlet>
18 <servlet-mapping>
19 <servlet-name>dispatcherServlet</servlet-name>
20 <!-- / 表示会匹配到所有的访问路径,但是不会匹配到像 *.jsp这样的方法url -->
21 <url-pattern>/</url-pattern>
22 </servlet-mapping>
23</web-app>
- 编写 Controller 类和视图页面,使用注解配置 Controller 类中业务方法的映射地址
UserController
1package com.soulboy.controller;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.RequestMapping;
5
6@Controller
7public class UserController {
8 @RequestMapping("/quick")
9 public String quick() {
10 // 业务逻辑
11 System.out.println("springmvc快速上手!");
12 // 视图跳转 : 请求转发
13 return "success";
14 }
15}
src/main/webapp/WEB-INF/pages/success.jsp
1<%--
2 Created by IntelliJ IDEA.
3 User: chao1
4 Date: 2022/12/26
5 Time: 18:41
6 To change this template use File | Settings | File Templates.
7--%>
8<%@ page contentType="text/html;charset=UTF-8" language="java" %>
9<html>
10<head>
11 <title>Title</title>
12</head>
13<body>
14 <h3>springmvc快速上手!</h3>
15</body>
16</html>
- 配置 SpringMVC 核心文件 spring-mvc.xml
src/main/resources/spring-mvc.xml
1<beans xmlns="http://www.springframework.org/schema/beans"
2 xmlns:mvc="http://www.springframework.org/schema/mvc"
3 xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6http://www.springframework.org/schema/beans/spring-beans.xsd
7http://www.springframework.org/schema/mvc
8http://www.springframework.org/schema/mvc/spring-mvc.xsd
9http://www.springframework.org/schema/context
10http://www.springframework.org/schema/context/spring-context.xsd">
11 <!--配置注解扫描-->
12 <context:component-scan base-package="com.soulboy.controller"/>
13
14 <!--处理器映射器和处理器适配器功能增强 :支持json的读写-->
15 <mvc:annotation-driven/>
16
17 <!--视图解析器-->
18 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
19 <property name="prefix" value="/WEB-INF/pages/"></property>
20 <property name="suffix" value=".jsp"></property>
21 </bean>
22</beans>
- 添加 Tomcat 服务器启动并测试
http://localhost:8080/springmvc_quickstart/quick
Web 工程执行流程
SpringMVC 是对 MVC 设计模式的一种实现,属于轻量级的 Web 框架。
SpringMVC 的开发步骤:
1.创建 Web 项目,导入 SpringMVC 相关坐标
2.配置 SpringMVC 前端控制器 DispathcerServlet
3.编写 Controller 类和视图页面
4.使用注解配置 Controller 类中业务方法的映射地址
5.配置 SpringMVC 核心文件 spring-mvc.xml
SpringMVC 组件概述
SpringMVC 的执行流程
- 用户发送请求至前端控制器 DispatcherServlet。
- DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
- 处理器映射器找到具体的处理器(可以根据 XML 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
- DispatcherServlet 调用 HandlerAdapter 处理器适配器。
- HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。
- Controller 执行完成返回 ModelAndView。
- HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。
- DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
- ViewReslover 解析后返回具体 View。
- DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet 将渲染后的视图响应响应用户。
SpringMVC 组件解析
- 前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。 - 处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。 - 处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 - 处理器:Handler【开发者编写】
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由 Handler 对具体的用户请求进行处理。 - 视图解析器:ViewResolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。 - 视图:View 【开发者编写】
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView 等。最常用的视图就是 JSP。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
- SpringMVC 的三大组件
处理器映射器:HandlerMapping
处理器适配器:HandlerAdapter
视图解析器:View Resolver - 开发者编写
处理器:Handler
视图:View
SpringMVC 注解解析
@Controller
SpringMVC 基于 Spring 容器,所以在进行 SpringMVC 操作时,需要将 Controller 存储到 Spring 容器中,如果使用 @Controller 注解标注的话,就需要使用:
1<!--配置注解扫描-->
2 <context:component-scan base-package="com.soulboy.controller"/>
@RequestMapping
1* 作用:
2 用于建立请求 URL 和处理请求方法之间的对应关系
3
4* 位置:
5 1.类上:请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以/开头。
6 它出现的目的是为了使我们的URL可以按照模块化管理:
7 用户模块
8 /user/add
9 /user/update
10 /user/delete
11 ...
12 账户模块
13 /account/add
14 /account/update
15 /account/delete
16 2.方法上:请求URL的第二级访问目录,和一级目录组成一个完整的 URL 路径。
17
18* 属性:
19 1.value:用于指定请求的URL。它和path属性的作用是一样的
20 2.method:用来限定请求的方式
21 3.params:用来限定请求参数的条件
22 例如:params={"accountName"} 表示请求参数中必须有accountName
23 pramss={"money!100"} 表示请求参数中money不能是100
SpringMVC 的请求
请求参数类型
客户端请求参数的格式是: name=value&name=value……
服务器要获取请求的参数的时候要进行类型转换,有时还需要进行数据的封装
SpringMVC 可以接收如下类型的参数:
- 基本类型参数
- 对象类型参数
- 数组类型参数
- 集合类型参数
获取基本类型参数
Controller 中的业务方法的参数名称要与请求参数的 name 一致,参数值会自动映射匹配。并且能自动做类型转换;自动的类型转换是指从 String 向其他类型的转换。
src/main/webapp/requestParam.jsp
1<%--
2 Created by IntelliJ IDEA.
3 User: chao1
4 Date: 2022/12/27
5 Time: 15:44
6 To change this template use File | Settings | File Templates.
7--%>
8<%@ page contentType="text/html;charset=UTF-8" language="java" %>
9<html>
10<head>
11 <title>Title</title>
12</head>
13<body>
14 <%-- 动态的获取项目路径:${pageContext.request.contextPath} get请求方式--%>
15 <a href="${pageContext.request.contextPath}/user/simpleParam?id=1&username=杰克">
16 基本类型
17 </a>
18</body>
19</html>
Controller:com/soulboy/controller/UserController.java
1package com.soulboy.controller;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.RequestMapping;
5
6@Controller
7@RequestMapping("/user")
8public class UserController {
9 @RequestMapping("/quick")
10 public String quick() {
11 // 业务逻辑
12 System.out.println("springmvc快速上手!");
13 // 视图跳转 : 请求转发
14 return "success";
15 }
16
17 /**
18 * 获取基本类型请求参数
19 */
20 @RequestMapping("simpleParam")
21 public String simpleParam(Integer id,String username) {
22 System.out.println(id);
23 System.out.println(username);
24 return "success";
25 }
26}
测试访问 url: http://localhost:8080/springmvc_quickstart/requestParam.jsp
获取对象类型参数
Controller 中的业务方法参数的 POJO 属性名与请求参数的 name 一致,参数值会自动映射匹配
JSP 页面:src/main/webapp/requestParam.jsp
1<form action="${pageContext.request.contextPath}/user/pojoParam" method="post">
2 编号:<input type="text" name="id"> <br>
3 用户名:<input type="text" name="username"> <br>
4 <input type="submit" value="对象类型">
5 </form>
POJO
1package com.soulboy.domain;
2
3public class User {
4 Integer id;
5 String username;
6
7 public Integer getId() {
8 return id;
9 }
10
11 public void setId(Integer id) {
12 this.id = id;
13 }
14
15 public String getUsername() {
16 return username;
17 }
18
19 public void setUsername(String username) {
20 this.username = username;
21 }
22
23 @Override
24 public String toString() {
25 return "User{" +
26 "id=" + id +
27 ", username='" + username + '\'' +
28 '}';
29 }
30}
Controller
com/soulboy/controller/UserController.java
1/**
2 * 获取对象类型请求参数
3 */
4 @RequestMapping("pojoParam")
5 public String pojoParam(User user) {
6 System.out.println(user);
7 return "success";
8 }
测试: http://localhost:8080/springmvc_quickstart/requestParam.jsp
1User{id=1, username='é????????'}
中文乱码过滤器
get 方法 tomcat8.5 内部已经解决,但是 post 方法需要自己解决。
当 post 请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤。
src/main/webapp/WEB-INF/web.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
5 version="4.0">
6
7 <!--配置全局过滤的filter-->
8 <filter>
9 <filter-name>CharacterEncodingFilter</filter-name>
10 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
11 <init-param>
12 <param-name>encoding</param-name>
13 <param-value>UTF-8</param-value>
14 </init-param>
15 </filter>
16 <filter-mapping>
17 <filter-name>CharacterEncodingFilter</filter-name>
18 <url-pattern>/*</url-pattern>
19 </filter-mapping>
20
21 <!--前端控制器-->
22 <servlet>
23 <servlet-name>dispatcherServlet</servlet-name>
24 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
25 <init-param>
26 <param-name>contextConfigLocation</param-name>
27 <param-value>classpath:spring-mvc.xml</param-value>
28 </init-param>
29 <!-- 在程序启动时候实例化servlet实例化初始化操作 -->
30 <load-on-startup>2</load-on-startup>
31 </servlet>
32 <servlet-mapping>
33 <servlet-name>dispatcherServlet</servlet-name>
34 <!-- / 表示会匹配到所有的访问路径,但是不会匹配到像 *.jsp这样的方法url -->
35 <url-pattern>/</url-pattern>
36 </servlet-mapping>
37</web-app>
获取数组类型参数
Controller 中的业务方法数组名称与请求参数的 name 一致,参数值会自动映射匹配。
JSP
1<form action="${pageContext.request.contextPath}/user/arrayParam">
2 编号:<br>
3 <input type="checkbox" name="ids" value="1">1<br>
4 <input type="checkbox" name="ids" value="2">2<br>
5 <input type="checkbox" name="ids" value="3">3<br>
6 <input type="checkbox" name="ids" value="4">4<br>
7 <input type="checkbox" name="ids" value="5">5<br>
8 <input type="submit" value="数组类型">
9 </form>
Controller
1/**
2 * 获取数组类型请求参数
3 */
4 @RequestMapping("/arrayParam")
5 public String arrayParam(Integer[] ids) {
6 System.out.println(Arrays.toString(ids));
7 return "success";
8 }
测试页面
http://localhost:8080/springmvc_quickstart/requestParam.jsp
获取数组类型参数
获得集合参数时,要将集合参数包装到一个 POJO 中才可以。
JSP
1搜索关键字:
2 <input type="text" name="keyword"> <br>
3 user对象:
4 <input type="text" name="user.id" placeholder="编号">
5 <input type="text" name="user.username" placeholder="姓名"><br>
6 list集合<br>
7 第一个元素:
8 <input type="text" name="userList[0].id" placeholder="编号">
9 <input type="text" name="userList[0].username" placeholder="姓名"><br>
10 第二个元素:
11 <input type="text" name="userList[1].id" placeholder="编号">
12 <input type="text" name="userList[1].username" placeholder="姓名"><br>
13 map集合<br>
14 第一个元素:
15 <input type="text" name="userMap['u1'].id" placeholder="编号">
16 <input type="text" name="userMap['u1'].username" placeholder="姓名"><br>
17 第二个元素:
18 <input type="text" name="userMap['u2'].id" placeholder="编号">
19 <input type="text" name="userMap['u2'].username" placeholder="姓名"><br>
20 <input type="submit" value="复杂类型">
21 </form>
QueryVo
1package com.soulboy.domain;
2
3import java.util.List;
4import java.util.Map;
5
6public class QueryVo {
7 private String keyword;
8 private User user;
9 private List<User> userList;
10 private Map<String, User> userMap;
11
12 public String getKeyword() {
13 return keyword;
14 }
15
16 public void setKeyword(String keyword) {
17 this.keyword = keyword;
18 }
19
20 public User getUser() {
21 return user;
22 }
23
24 public void setUser(User user) {
25 this.user = user;
26 }
27
28 public List<User> getUserList() {
29 return userList;
30 }
31
32 public void setUserList(List<User> userList) {
33 this.userList = userList;
34 }
35
36 public Map<String, User> getUserMap() {
37 return userMap;
38 }
39
40 public void setUserMap(Map<String, User> userMap) {
41 this.userMap = userMap;
42 }
43
44 @Override
45 public String toString() {
46 return "QueryVo{" +
47 "keyword='" + keyword + '\'' +
48 ", user=" + user +
49 ", userList=" + userList +
50 ", userMap=" + userMap +
51 '}';
52 }
53}
Controller
1/**
2 * 获取集合类型请求参数
3 */
4 @RequestMapping("/queryParam")
5 public String queryParam(QueryVo queryVo) {
6 System.out.println(queryVo);
7 return "success";
8 }
测试:http://localhost:8080/springmvc_quickstart/requestParam.jsp
QueryVo{keyword='语文', user=User{id=1, username='高晓松'}, userList=[User{id=1, username='秃秃'}, User{id=2, username='妞妞'}], userMap={u1=User{id=1, username='高中美'}, u2=User{id=2, username='高中直'}}}
自定义类型转换器
SpringMVC 默认已经提供了一些常用的类型转换器;例如:客户端提交的字符串转换成 int 型进行参数设置,日期格式类型要求为:yyyy/MM/dd 不然的话会报错,对于特有的行为,SpringMVC 提供了自定义类型转换器方便开发者自定义处理。
JSP 页面
1<form action="${pageContext.request.contextPath}/user/converterParam">
2 生日:<input type="text" name="birthday">
3 <input type="submit" value="自定义类型转换器">
4 </form>
Controller
1/**
2 * 自定义类型转换器(自定义类型)
3 */
4 @RequestMapping("/converterParam")
5 public String converterParam(Date birthday) {
6 System.out.println(birthday);
7 return "success";
8 }
自定义类型转换器
com/soulboy/converter/DateConverter.java
1package com.soulboy.converter;
2
3
4import org.springframework.core.convert.converter.Converter;
5
6import java.text.ParseException;
7import java.text.SimpleDateFormat;
8import java.util.Date;
9
10public class DateConverter implements Converter<String,Date> {
11
12 // s 就是表单传递过来的请求参数
13 @Override
14 public Date convert(String s) {
15 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
16 Date date = null;
17 try {
18 date = format.parse(s);
19 } catch (ParseException e) {
20 e.printStackTrace();
21 }
22 return date;
23 }
24}
配置自定义转换器
spring-mvc.xml
1<!--处理器映射器和处理器适配器功能增强 :支持json的读写-->
2 <mvc:annotation-driven conversion-service="conversionService"/>
3
4 <!--自定义转换器配置-->
5 <bean id="conversionService"
6 class="org.springframework.context.support.ConversionServiceFactoryBean">
7 <property name="converters">
8 <set>
9 <bean class="com.soulboy.converter.DateConverter"></bean>
10 </set>
11 </property>
12 </bean>
相关注解
@RequestParam
当请求的参数 name 名称与 Controller 的业务方法参数名称不一致时,就需要通过 @RequestParam 注解显示的绑定
JSP 页面
1<a href="${pageContext.request.contextPath}/user/findByPage?pageNo=2">
2 分页查询
3 </a>
Controller
1/**
2 @RequestParam() 注解
3 defaultValue 设置参数默认值
4 name 匹配页面传递参数的名称
5 required 设置是否必须传递参数,默认值为true;如果设置了默认值,值自动改为false
6 */
7 @RequestMapping("/findByPage")
8 public String findByPage(@RequestParam(name = "pageNo", defaultValue = "1")
9 Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) {
10 System.out.println(pageNum);
11 System.out.println(pageSize);
12 return "success";
13 }
@RequestHeader
获取请求头的数据。
UserController.java
1/**
2 * 获取请求头数据
3 */
4 @RequestMapping("/requestHead")
5 public String requestHead(@RequestHeader("cookie") String cookie) {
6 System.out.println(cookie);
7 return "success";
8 }
测试:http://localhost:8080/springmvc_quickstart/user/requestHead
JSESSIONID=F6D8E359D858F903C53461CB806F50C0
@CookieValue
获取 cookie 中的数据。
1/**
2 * 获取cookie中的数据。
3 */
4 @RequestMapping("/cookieValue")
5 public String cookieValue(@CookieValue("JSESSIONID") String jesessionId) {
6 System.out.println(jesessionId);
7 return "success";
8 }
测试:http://localhost:8080/springmvc_quickstart/user/cookieValue
F6D8E359D858F903C53461CB806F50C0
获取 Servlet 相关 API
SpringMVC 支持使用原始 ServletAPI 对象作为控制器方法的参数进行注入,如果在 controller 的中需要使用原始的 ServletAPI 的话,常用的对象如下:
1/**
2 * 获取原始ServletAPI对象
3 */
4 @RequestMapping("/servletAPI")
5 public String servletAPI(HttpServletRequest request, HttpServletResponse
6 response, HttpSession session) {
7 System.out.println(request);
8 System.out.println(response);
9 System.out.println(session);
10 return "success";
11 }
测试:http://localhost:8080/springmvc_quickstart/user/servletAPI
1org.apache.catalina.connector.RequestFacade@50f4a1a3
2org.apache.catalina.connector.ResponseFacade@34797d7c
3org.apache.catalina.session.StandardSessionFacade@5ff70c1e
SpringMVC 的响应
SpringMVC 响应方式
页面跳转
11. 返回字符串逻辑视图(请求转发)
22. void原始ServletAPI
33. ModelAndView
返回数据
11. 直接返回字符串数据
2```java
3@RequestMapping("/returnVoid")
4 public void returnVoid(HttpServletRequest request, HttpServletResponse response)
5 throws Exception {
6 //三选一
7 // 1.通过response直接响应数据
8 response.setContentType("text/html;charset=utf-8");
9 response.getWriter().write("拉勾网");
10 request.setAttribute("username", "拉勾教育");
11 }
- 将对象或集合转为 JSON 返回
返回字符串逻辑视图(页面跳转)
直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转到指定页面
1@RequestMapping("/returnString")
2 public String returnString() {
3 return "success";
4 }
void 原始 ServletAPI(页面跳转)
通过 request、response 对象实现响应
1@RequestMapping("/returnVoid")
2 public void returnVoid(HttpServletRequest request, HttpServletResponse response)
3 throws Exception {
4 //三选一
5 // 1.通过response直接响应数据
6 response.setContentType("text/html;charset=utf-8");
7 response.getWriter().write("拉勾网");
8 request.setAttribute("username", "拉勾教育");
9
10 // 2.通过request实现转发
11 request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
12
13 // 3.通过response实现重定向:重定向地址栏会发生改变
14 response.sendRedirect(request.getContextPath() + "/index.jsp");
15 }
转发和重定向
forward 转发
企业开发我们一般使用返回字符串逻辑视图实现页面的跳转,这种方式其实就是请求转发。
我们也可以写成:forward 转发
如果用了 forward:则路径必须写成实际视图 url,不能写逻辑视图。它相当于:
request.getRequestDispatcher("url").forward(request,response)
使用请求转发,既可以转发到 JSP,也可以转发到其他的控制器方法。
1@RequestMapping("/forward")
2 public String forward(Model model) {
3 // 还想在模型中设置一些值(Model相当于域), 在JSP页面中使取值方法如下:${username}
4 model.addAttribute("username", "soulboy");
5 // 使用请求转发,既可以转发到jsp,也可以转发到其他的控制器方法。forward转发
6 // return "forward:/product/findAll";
7 return "forward:/WEB-INF/pages/success.jsp";
8 }
Redirect 重定向
我们可以不写虚拟目录,SpringMVC 框架会自动拼接,并且将 Model 中的数据拼接到 url 地址上
1@RequestMapping("/redirect")
2 public String redirect(Model model) {
3 //底层使用的还是request.setAttribute("username","拉钩教育") 域范围:一次请求 重定向是两次请求,所以 ${username} 取不到,要使用转发才可以
4 model.addAttribute("username", "拉勾教育");
5 // 不能重定向到WEB-INF目录下的页面
6 return "redirect:/index.jsp";
7 }
ModelAndVie(页面跳转)
既可以设置模型数据,又可以设置视图名称
方式一
在 Controller 中方法创建并返回 ModelAndView 对象,并且设置视图名称
1@RequestMapping("/returnModelAndView1")
2 public ModelAndView returnModelAndView1() {
3 /*
4 Model:模型 作用封装数据
5 View:视图 作用展示数据
6 */
7 ModelAndView modelAndView = new ModelAndView();
8 //设置模型数据
9 modelAndView.addObject("username", " lagou");
10 //设置视图名称
11 modelAndView.setViewName("success");
12 return modelAndView;
13 }
方式二
在 Controller 中方法形参上直接声明 ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面
1@RequestMapping("/returnModelAndView2")
2 public ModelAndView returnModelAndView2(ModelAndView modelAndView) {
3 //设置模型数据
4 modelAndView.addObject("username", "itheima");
5 //设置视图名称
6 modelAndView.setViewName("success");
7 return modelAndView;
8 }
@SessionAttributes
如果在多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在 session 中存放的数据范围,Spring MVC 将存放在 model 中对应的数据暂存到 HttpSession 中。
com.soulboy.controller.UserController
1@Controller
2@RequestMapping("/user")
3@SessionAttributes("username") //向request域存入的key为username时,同步到session域中
4public class UserController {
5
6 @RequestMapping("/forward")
7 public String forward(Model model) {
8 model.addAttribute("username", "子慕");
9 return "forward:/WEB-INF/pages/success.jsp";
10 }
11
12 @RequestMapping("/returnString")
13 public String returnString() {
14 return "success";
15 }
16}
src/main/webapp/WEB-INF/pages/success.jsp
1<%--
2 Created by IntelliJ IDEA.
3 User: chao1
4 Date: 2022/12/26
5 Time: 18:41
6 To change this template use File | Settings | File Templates.
7--%>
8<%@ page contentType="text/html;charset=UTF-8" language="java" %>
9<html>
10<head>
11 <title>Title</title>
12</head>
13<body>
14 <h3>springmvc快速上手!…… ${username}</h3>
15</body>
16</html>
测试
1http://localhost:8080/springmvc_quickstart/user/forward
2 springmvc快速上手!…… 子慕
3
4http://localhost:8080/springmvc_quickstart/user/returnString
5 springmvc快速上手!…… 子慕
知识小结
1* 页面跳转采用返回字符串逻辑视图
2 1.forward转发
3 可以通过Model向request域中设置数据
4 2.redirect重定向
5 直接写资源路径即可,虚拟目录springMVC框架自动完成拼接
6
7* 数据存储到request域中
8 Model model
9 model.addAttribute("username", "子慕");
静态资源访问的开启
当有静态资源需要加载时,比如 jQuery 文件,通过谷歌开发者工具抓包发现,没有加载到 jQuery 文件,原因是 SpringMVC 的前端控制器 DispatcherServlet 的 url-pattern 配置的是 /(缺省),代表对所有的静态资源都进行处理操作,这样就不会执行 Tomcat 内置的 DefaultServlet 处理,我们可以通过以下两种方式指定放行静态资源:
方式一(放行局部静态资源)
spring-mvc.xml
1<!--在springmvc配置文件中指定放行资源 mapping:放行的映射路径 location:静态资源所在的目录(webapp下面的目录)-->
2 <mvc:resources mapping="/js/**" location="/js/"/>
3 <mvc:resources mapping="/css/**" location="/css/"/>
4 <mvc:resources mapping="/img/**" location="/img/"/>
方式二(放行全部静态资源)
spring-mvc.xml
1<!--在springmvc配置文件中开启DefaultServlet处理静态资源-->
2 <mvc:default-servlet-handler/>
AJAX 异步交互
SpringMVC 默认用 MappingJackson2HttpMessageConverter 对 JSON 数据进行转换,需要加入 jackson 的包;同时使用 <mvc:annotation-driven />
1<dependency>
2 <groupId>com.fasterxml.jackson.core</groupId>
3 <artifactId>jackson-databind</artifactId>
4 <version>2.9.8</version>
5 </dependency>
6 <dependency>
7 <groupId>com.fasterxml.jackson.core</groupId>
8 <artifactId>jackson-core</artifactId>
9 <version>2.9.8</version>
10 </dependency>
11 <dependency>
12 <groupId>com.fasterxml.jackson.core</groupId>
13 <artifactId>jackson-annotations</artifactId>
14 <version>2.9.0</version>
15 </dependency>
@RequestBody
该注解用于 Controller 的方法的形参声明,当使用 AJAX 提交并指定 contentType 为 JSON 形式时,通过 HttpMessageConverter 接口转换为对应的 POJO 对象。
JSP
1<%--
2 Created by IntelliJ IDEA.
3 User: chao1
4 Date: 2022/12/29
5 Time: 14:42
6 To change this template use File | Settings | File Templates.
7--%>
8<%@ page contentType="text/html;charset=UTF-8" language="java" %>
9<html>
10<head>
11 <title>Title</title>
12</head>
13<body>
14<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
15 <%-- ajax异步交互 --%>
16 <button id="btn1">ajax异步提交</button>
17 <script>
18 $("#btn1").click(function (){
19 let url = '${pageContext.request.contextPath}/user/ajaxRequest';
20 let data = '[{"id":1,"username":"高中美"},{"id":2,"username":"妞妞"}]';
21
22 $.ajax({
23 type: 'POST',
24 url: url,
25 data: data,
26 contentType: 'application/json;charset=utf-8',
27 success: function (resp) {
28 alert(resp);
29 }
30 })
31 })
32
33 </script>
34
35
36</body>
37</html>
UserController
1/*
2 ajax异步交互
3 [{"id":1,"username":"高中美"},{"id":2,"username":"妞妞"}]
4 */
5 @RequestMapping("/ajaxRequest")
6 public void ajaxRequest(@RequestBody List<User> list) {
7 System.out.println(list);
8 }
测试 http://localhost:8080/springmvc_quickstart/ajax.jsp
[User{id=1, username='高中美'}, User{id=2, username='妞妞'}]
@ResponseBody
该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的数据如:json,xml 等,通过 Response 响应给客户端。
JSP
1<%--
2 Created by IntelliJ IDEA.
3 User: chao1
4 Date: 2022/12/29
5 Time: 14:42
6 To change this template use File | Settings | File Templates.
7--%>
8<%@ page contentType="text/html;charset=UTF-8" language="java" %>
9<html>
10<head>
11 <title>Title</title>
12</head>
13<body>
14<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
15 <%-- ajax异步交互 --%>
16 <button id="btn1">ajax异步提交</button>
17 <script>
18 $("#btn1").click(function (){
19 let url = '${pageContext.request.contextPath}/user/ajaxRequest';
20 let data = '[{"id":1,"username":"高中美"},{"id":2,"username":"妞妞"}]';
21
22 $.ajax({
23 type: 'POST',
24 url: url,
25 data: data,
26 contentType: 'application/json;charset=utf-8',
27 success: function (resp) {
28 alert(JSON.stringify(resp));
29 }
30 })
31 })
32 </script>
33
34
35</body>
36</html>
UserController
1/*
2 ajax异步交互
3 [{"id":1,"username":"高中美"},{"id":2,"username":"妞妞"}]
4 */
5 @RequestMapping("/ajaxRequest")
6 @ResponseBody //转换为json串返回
7 public List<User> ajaxRequest(@RequestBody List<User> list) {
8 System.out.println(list);
9 return list;
10 }
RESTFul
RESTFul 是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。
RESTFul 风格的请求是使用“url+ 请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
- GET:读取(Read)
- POST:新建(Create)
- PUT:更新(Update)
- DELETE:删除(Delete)
@PathVariable
用来接收 RESTFul 风格请求地址中占位符的值
@RestController
RESTFul 风格多用于前后端分离项目开发,前端通过 AJAX 与服务器进行异步交互,我们处理器通常返回的是 JSON 数据所以使用 @RestController 来替代 @Controller 和 @ResponseBody 两个注解。
RESTFul 示例
1package com.soulboy.controller;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.*;
5
6//@Controller
7@RestController //组合主键: @Controller + @ResponseBody
8@RequestMapping("/restful")
9public class RestFulController {
10 /*
11 根据id进行查询
12 */
13 //@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
14 @GetMapping(value = "/user/{id}")
15 //@ResponseBody
16 public String findById(@PathVariable Integer id) {
17 //调用service层方法完成对id为2的这条记录的查询
18 //http://localhost:8080/springmvc_quickstart/restful/user/2
19 return "findById: " + id;
20 }
21
22 /*
23 新增方法
24 */
25 @PostMapping(value = "/user")
26 // @ResponseBody
27 public String post() {
28 return "post";
29 }
30
31 /*
32 更新方法
33 */
34 @PutMapping(value = "/user")
35 // @ResponseBody
36 public String put() {
37 return "put";
38 }
39
40 /*
41 删除
42 */
43 @DeleteMapping(value = "/user/{id}")
44 // @ResponseBody
45 public String delete(@PathVariable Integer id) {
46 return "delete:"+ id;
47 }
48}
文件上传
文件上传三要素
表单项 type="file"
表单的提交方式 method="POST"
表单的 enctype 属性是多部分表单形式 enctype=“multipart/form-data"
文件上传原理
当 form 表单修改为多部分表单时,request.getParameter()将失效。
当 form 表单的 enctype 取值为 application/x-www-form-urlencoded 时,
- form 表单的正文内容格式是: name=value&name=value
当 form 表单的 enctype 取值为 mutilpart/form-data 时,请求正文内容就变成多部分形式:
单文件上传
步骤分析
11. 导入fileupload和io坐标
22. 配置文件上传解析器
33. 编写文件上传代码
- 导入 fileupload 和 io 坐标
1<dependency>
2 <groupId>commons-fileupload</groupId>
3 <artifactId>commons-fileupload</artifactId>
4 <version>1.3.3</version>
5 </dependency>
6 <dependency>
7 <groupId>commons-io</groupId>
8 <artifactId>commons-io</artifactId>
9 <version>2.6</version>
10 </dependency>
- 配置文件上传解析器
spring-mvc.xml
1<!--文件上传解析器-->
2 <bean id="multipartResolver"
3 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
4 <!-- 设定文件上传的最大值为5MB,5*1024*1024 -->
5 <property name="maxUploadSize" value="5242880"></property>
6 <!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
7 <property name="maxInMemorySize" value="40960"></property>
8 </bean>
- 编写文件上传代码
JSP 页面
src/main/webapp/fileupload.jsp
1<%--
2 Created by IntelliJ IDEA.
3 User: chao1
4 Date: 2022/12/29
5 Time: 17:51
6 To change this template use File | Settings | File Templates.
7--%>
8<%@ page contentType="text/html;charset=UTF-8" language="java" %>
9<html>
10<head>
11 <title>Title</title>
12</head>
13<body>
14 <%-- 编写一个满足文件上传三要素的表单
15 1.表单的提交方式必须是post
16 2.表单的enctype属性必须修改成multipart/form-data
17 3.表单中必须要有文件上传项
18 --%>
19 <form action="${pageContext.request.contextPath}/fileUpload" method="post"
20 enctype="multipart/form-data">
21 名称:<input type="text" name="username"> <br>
22 文件:<input type="file" name="filePic"> <br>
23 <input type="submit" value="单文件上传">
24 </form>
25</body>
26</html>
FileUploadController.java
1package com.soulboy.controller;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.RequestMapping;
5import org.springframework.web.multipart.MultipartFile;
6
7import java.io.File;
8import java.io.IOException;
9
10@Controller
11public class FileUploadController {
12 /*
13 单文件上传
14 */
15 @RequestMapping("/fileUpload")
16 public String fileUpload(String username, MultipartFile filePic) throws IOException {
17 //打印名称
18 System.out.println(username);
19 // 获取原始的文件上传名 a.txt
20 String originalFilename = filePic.getOriginalFilename();
21 //保存文件
22 filePic.transferTo(new File("D:/Project/Java/upload/" + originalFilename));
23 return "success";
24 }
25}
测试页面
http://localhost:8080/springmvc_quickstart/fileupload.jsp
多文件上传
JSP 页面
1<%-- 编写一个满足文件上传三要素的表单
2 1.表单的提交方式必须是post
3 2.表单的enctype属性必须修改成multipart/form-data
4 3.表单中必须要有文件上传项
5 --%>
6 <form action="${pageContext.request.contextPath}/filesUpload" method="post"
7 enctype="multipart/form-data">
8 名称:<input type="text" name="username"> <br>
9 文件:<input type="file" name="filePic"> <br>
10 文件:<input type="file" name="filePic"> <br>
11 <input type="submit" value="多文件上传">
12 </form>
FileUploadController.java
1package com.soulboy.controller;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.RequestMapping;
5import org.springframework.web.multipart.MultipartFile;
6
7import java.io.File;
8import java.io.IOException;
9
10@Controller
11public class FileUploadController {
12 /*
13 多文件上传
14 */
15 @RequestMapping("/filesUpload")
16 public String filesUpload(String username, MultipartFile[] filePic) throws IOException {
17 //打印名称
18 System.out.println(username);
19 for (MultipartFile multipartFile : filePic) {
20 // 获取原始的文件上传名
21 String originalFilename = multipartFile.getOriginalFilename();
22 //保存文件
23 multipartFile.transferTo(new File("D:/Project/Java/upload/" + originalFilename));
24 }
25 return "success";
26 }
27}
测试页面
http://localhost:8080/springmvc_quickstart/fileupload.jsp
异常处理
异常处理的思路
在 Java 中,对于异常的处理一般有两种方式:
- 一种是当前方法捕获处理(try-catch),这种处理方式会造成业务代码和异常处理代码的耦合。
- 另一种是自己不处理,而是抛给调用者处理(throws),调用者再抛给它的调用者,也就是一直向上抛。
在这种方法的基础上,衍生出了 SpringMVC 的异常处理机制。
系统的 dao、service、controller 出现都通过 throws Exception 向上抛出,最后由 SpringMVC 前端控制器交由异常处理器进行异常处理,如下图:
自定义异常处理器
步骤分析
11. 创建异常处理器类实现HandlerExceptionResolver
22. 配置异常处理器
33. 编写异常页面
44. 测试异常跳转
- 创建异常处理器类实现 HandlerExceptionResolver、JSP 页面、Controller
GlobalExceptionResolver.java
1public class GlobalExceptionResolver implements HandlerExceptionResolver {
2 /*
3 Exception e : 实际抛出的异常对象
4
5 */
6 @Override
7 public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
8 //具体的异常处理,产生异常后,跳转到一个最终的异常页面
9 ModelAndView modelAndView = new ModelAndView();
10 modelAndView.addObject("error", e.getMessage());
11 modelAndView.setViewName("error"); //src/main/webapp/WEB-INF/pages/error.jsp
12 return modelAndView;
13 }
14}
**ExceptionController **
1package com.soulboy.controller;
2
3import org.springframework.web.bind.annotation.RequestMapping;
4
5public class ExceptionController {
6 @RequestMapping("/testException")
7 public String testException() {
8 int i = 1 / 0;
9 return "success";
10 }
11}
- 配置异常处理器
spring-mvc.xml
1<!--配置自定义的异常处理器-->
2 <bean id="globalExceptionResolver" class="com.soulboy.exception.GlobalExceptionResolver"></bean>
- 编写异常页面
error.jsp
1<%@ page contentType="text/html;charset=UTF-8" language="java" %>
2<html>
3<head>
4 <title>Title</title>
5</head>
6<body>
7 这是一个最终异常的显示页面!!!
8</body>
9</html>
- 测试异常跳转
http://localhost:8080/springmvc_quickstart/testException
Web 的处理异常机制
测试
测试 URL 并不存在
http://localhost:8080/springmvc_quickstart/testException111
src/main/webapp/WEB-INF/web.xml
1<!-- 处理404异常 -->
2 <error-page>
3 <error-code>404</error-code>
4 <location>/404.jsp</location>
5 </error-page>
6
7 <!-- 处理500异常 -->
8 <error-page>
9 <error-code>500</error-code>
10 <location>/500.jsp</location>
11 </error-page>
拦截器
拦截器(interceptor)的作用
Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器(Controller 中的目标方法)进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是 AOP 思想的具体实现。
拦截器和过滤器区别
关于 interceptor 和 filter 的区别,如图所示:
快速入门
步骤分析
11. 创建拦截器类实现HandlerInterceptor接口
22. 配置拦截器
33. 测试拦截器的拦截效果
- 创建拦截器类实现 HandlerInterceptor 接口
MyInterceptor1
1package com.soulboy.interceptor;
2
3import org.springframework.web.servlet.HandlerInterceptor;
4import org.springframework.web.servlet.ModelAndView;
5
6import javax.servlet.http.HttpServletRequest;
7import javax.servlet.http.HttpServletResponse;
8
9public class MyInterceptor1 implements HandlerInterceptor {
10 /*
11 preHandle: 在目标方法执行之前进行拦截
12 return false代表不放行,后续的所有方法都不会执行
13 return true代表放行,接着执行后续的所有方法
14 */
15 @Override
16 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
17 System.out.println("preHandle...");
18 return true;
19 }
20
21 /*
22 postHandle: 在目标方法执行之后,视图对象返回之前所执行的方法
23 return false代表不放行,后续的所有方法都不会执行
24 return true代表放行,接着执行后续的所有方法
25 */
26 @Override
27 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
28 System.out.println("postHandle...");
29 }
30
31 /*
32 afterCompletion: 在流程都执行完成后,执行的方法
33 */
34 @Override
35 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
36 System.out.println("afterCompletion...");
37 }
38}
- 配置拦截器
spring-mvc.xml
1<!--配置拦截器-->
2 <mvc:interceptors>
3 <mvc:interceptor>
4 <!--对哪些资源执行拦截操作-->
5 <mvc:mapping path="/**"/>
6 <bean class="com.soulboy.interceptor.MyInterceptor1"/>
7 </mvc:interceptor>
8 </mvc:interceptors>
- 测试拦截器的拦截效果
TargetController
1package com.soulboy.controller;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.RequestMapping;
5
6@Controller
7public class TargetController {
8 @RequestMapping("/target")
9 public String targetMethod() {
10 System.out.println("目标方法执行了...");
11 return "success";
12 }
13}
编写 JSP 页面
1<%@ page contentType="text/html;charset=UTF-8" language="java" %>
2<html>
3<head>
4 <title>Title</title>
5</head>
6<body>
7 <h3>springmvc快速上手!…… ${username}</h3>
8 <% System.out.println("视图执行了....");%>
9</body>
10</html>
测试
http://localhost:8080/springmvc_quickstart/target
1preHandle...
2目标方法执行了...
3postHandle...
4视图执行了....
5afterCompletion...
拦截器链
开发中拦截器可以单独使用,也可以同时使用多个拦截器形成一条拦截器链。开发步骤和单个拦截器是一样的,只不过注册的时候注册多个,注意这里注册的顺序就代表拦截器执行的顺序。
同上,再编写一个 MyHandlerInterceptor2 操作,测试执行顺序:
需要注意拦截器链的执行顺序
方法名 | 说明 | 顺序 |
---|---|---|
preHandle() | 方法将在请求处理之前进行调用,该方法的返值是布尔值 Boolean 类型的当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时就会继续调用下一个 Interceptor 的 preHandle 方法 | 串行 |
postHandle() | 该方法是在当前请求进行处理之后被调用,前提是 preHandle 方法的返回值为 true 时才能被调用,且它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作 | 逆序 |
afterCompletion() | 该方法将在整个请求结束之后,也就是在 DispatcherServlet 染了对应的视图之后执行,前提是 preHandle 方法的返回值为 true 时才能被调用 | 逆序 |
MyInterceptor2
1package com.soulboy.interceptor;
2
3import org.springframework.web.servlet.HandlerInterceptor;
4import org.springframework.web.servlet.ModelAndView;
5
6import javax.servlet.http.HttpServletRequest;
7import javax.servlet.http.HttpServletResponse;
8
9public class MyInterceptor2 implements HandlerInterceptor {
10 /*
11 preHandle: 在目标方法执行之前进行拦截
12 return false代表不放行,后续的所有方法都不会执行
13 return true代表放行,接着执行后续的所有方法
14 */
15 @Override
16 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
17 System.out.println("preHandle2...");
18 return true;
19 }
20
21 /*
22 postHandle: 在目标方法执行之后,视图对象返回之前所执行的方法
23 return false代表不放行,后续的所有方法都不会执行
24 return true代表放行,接着执行后续的所有方法
25 */
26 @Override
27 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
28 System.out.println("postHandle2...");
29 }
30
31 /*
32 afterCompletion: 在流程都执行完成后,执行的方法
33 */
34 @Override
35 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
36 System.out.println("afterCompletion2...");
37 }
38}
spring-mvc.xml
1<!--配置拦截器-->
2 <mvc:interceptors>
3 <mvc:interceptor>
4 <!--对哪些资源执行拦截操作-->
5 <mvc:mapping path="/**"/>
6 <bean class="com.soulboy.interceptor.MyInterceptor1"/>
7 </mvc:interceptor>
8 <mvc:interceptor>
9 <!--对哪些资源执行拦截操作-->
10 <mvc:mapping path="/**"/>
11 <bean class="com.soulboy.interceptor.MyInterceptor2"/>
12 </mvc:interceptor>
13 </mvc:interceptors>
测试
http://localhost:8080/springmvc_quickstart/target
1preHandle1...
2preHandle2...
3目标方法执行了...
4postHandle2...
5postHandle1...
6视图执行了....
7afterCompletion2...
8afterCompletion1...