SpringMVC的拦截器
1 SpringMVC中拦截器
1.1 作用
作用:类似于javaweb中的Filter,用来对请求进行拦截,可以将多个Controller中执行的共同代码放入拦截器中执行,减少Controller类中代码的冗余.
1.2 特点
拦截器器只能拦截Controller的请求,不能拦截jsp。
拦截器可中断用户的请求轨迹。
- 请求先经过拦截器,之后之后还会经过拦截器。
1.3开发拦截器
如图所示:
1.引入依赖的代码如下:
<?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.txw</groupId>
<artifactId>springmvc_03</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!--相关的依赖-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!--springmvc核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!--servlet-api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--文件上传的依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
<!--json依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>springmvc_03</finalName>
</build>
</project>
如图所示:
2.编写MyInterceptor的代码如下:
package com.txw.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
* @author Adair
* E-mail: 1578533828@qq.com
*/
@SuppressWarnings("all") // 注解警告信息
public class MyInterceptor implements HandlerInterceptor {
/**
* 前置处理 请求到达拦截器后会优先执行指定内容
* 返回值:代表是否执行 false:不执行 中断请求 true:放行 执行后续Controller
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("-------------1-------------------");
return true;
}
/**
* 请求后的处理 在Controller返回后执行指定内容 类似:AOP中的后置通知
* postHandler执行完成之后开始给客户端进行响应
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("-------------3-------------------");
}
/**
* 响应处理 当Controller响应完客户端之后会执行指定内容 Controller发生异常之后也会执行指定内容。类似:finlly{}
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @param e
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("-------------4-------------------");
}
}
如图所示:
3.编写springmvc.xml的代码如下:
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.txw"/>
<!--配置处理器映射器 和处理器适配器-->
<mvc:annotation-driven/>
<!--注册视图解析器 注入 前缀 后缀-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--放行静态资源-->
<mvc:default-servlet-handler/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--控制文件上传大小单位字节 默认没有大小限制 这里是2-->
<property name="maxUploadSize" value="2097152"/>
</bean>
<!--配置拦截器-->
<bean id="myInterceptor" class="com.txw.interceptor.MyInterceptor"></bean>
<!--指定拦截器要拦截哪些Controller-->
<mvc:interceptors>
<!--单个拦截器的配置-->
<mvc:interceptor>
<!--要拦截的Controller-->
<mvc:mapping path="/test/*"/>
<!--不要拦截的Controller-->
<mvc:exclude-mapping path="/test/test1"/>
<!--指定当前使用哪个拦截器-->
<ref bean="myInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
如图所示:
/*``: 代表拦截所有请求路径
。
4.编写TestController的代码如下:
package com.txw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Adair
* E-mail: 1578533828@qq.com
*/
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("test1")
public String test1(){
System.out.println("-------------2-------------------");
return "index";
}
@RequestMapping("test2")
public String test2(){
System.out.println("-------------2-------------------");
return "index";
}
}
如图所示:
6.通过浏览器访问:http://localhost:8080/test/test1,如图所示:
控制台打印结果,如图所示:
6.通过浏览器访问:http://localhost:8080/test/test2,如图所示:
控制台打印结果,如图所示:
7.编写error.jsp的代码如下:
%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
<title>登录页面</title>
<meta charset="UTF-8">
</head>
<body>
<h1>输入用户名</h1>
<h1>输入密码</h1>
</body>
</html>
如图所示:
8.编写User的代码如下:
package com.txw.entity;
import java.util.Date;
/**
* @author Adair
* E-mail: 1578533828@qq.com
*/
public class User {
private String name;
private Integer age;
private Double salary;
private Boolean sex;
private Date birthday;
public User() {
}
public User(String name, Integer age, Double salary, Boolean sex, Date birthday) {
this.name = name;
this.age = age;
this.salary = salary;
this.sex = sex;
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
", sex=" + sex +
", birthday=" + birthday +
'}';
}
}
如图所示:
9.编写MyInterceptor的代码如下:
package com.txw.interceptor;
import com.txw.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
* @author Adair
* E-mail: 1578533828@qq.com
*/
@SuppressWarnings("all") // 注解警告信息
public class MyInterceptor implements HandlerInterceptor {
/**
* 前置处理 请求到达拦截器后会优先执行指定内容
* 返回值:代表是否执行 false:不执行 中断请求 true:放行 执行后续Controller
* @param request 请求响应对象
* @param response 请求响应对象
* @param o 要访问的目标Controller服务方法
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
System.out.println("-------------1-------------------");
System.out.println(o);
// 模拟登录验证 session获取用户对象 进行判断
/* User user = (User) request.getSession().getAttribute("user");
if (user != null){
return true;
}
// 跳转登录页面 error.jsp
response.sendRedirect(request.getContextPath() + "/error.jsp");*/
// request.getRequestDispatcher("/error.jsp").forward(request,response);
return true;
}
/**
* 请求后的处理 在Controller返回后执行指定内容 类似:AOP中的后置通知
* postHandler执行完成之后开始给客户端进行响应
* @param request
* @param response
* @param o
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("-------------3-------------------");
System.out.println("name: " + modelAndView.getModel().get("name"));
System.out.println("即将跳转的位置为:" + modelAndView.getViewName());
}
/**
* 响应处理 当Controller响应完客户端之后会执行指定内容 Controller发生异常之后也会执行指定内容。类似:finlly{}
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @param e
* @throws Exception 封装的是Controller中出现的异常对象
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
System.out.println("-------------4-------------------");
System.out.println(e.getMessage());
}
}
如图所示:
10.编写TestController的代码如下:
package com.txw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Adair
* E-mail: 1578533828@qq.com
*/
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("test1")
public String test1(Model model){
System.out.println("-------------2-------------------");
int i = 1 / 0;
model.addAttribute("name","Adair");
// SpringMVC自动将request作用域和返回值封装为ModelAndView
return "index";
}
@RequestMapping("test2")
public String test2(){
System.out.println("-------------2-------------------");
return "index";
}
}
如图所示:
拦截器运行顺序,如图所示:
2 SpringMVC全局异常处理
如图所示:
2.1 作用
`当控制器中某个方法在运行过程中突然发生运行时异常时,为了增加用户体验对于用户不能出现500错误代码,应该给用户良好展示错误界面,全局异常处理就能更好解决这个问题.。
2.2 全局异常处理开发
1.编写CustomerHanlderExceptionResolver的代码如下:
package com.txw.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
/**
* 全局异常处理类
* @author Adair
* E-mail: 1578533828@qq.com
*/
@SuppressWarnings("all") // 注解警告信息
public class CustomerHanlderExceptionResolver implements HandlerExceptionResolver {
/**
* 方法功能:一旦程序出现异常的处理方案
* @param request 请求响应对象
* @param response 请求响应对象
* @param o 发生异常的Controller访问方法对象
* @param e 发生的异常对象
* @return
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
// 发生异常跳转到专门准备的异常处理页面 /error.jsp 等价于 return ""
try {
modelAndView.setViewName("redirect:/error.jsp?message=" + URLEncoder.encode(e.getMessage(),"UTF-8"));
} catch (Exception exception) {
exception.printStackTrace();
}
return modelAndView;
}
}
如图所示:
2.编写springmvc.xml的代码如下:
<!--配置全局异常处理类-->
<bean class="com.txw.exception.CustomerHanlderExceptionResolver"/>
如图所示:
3.编写TestController的代码如下:
package com.txw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Adair
* E-mail: 1578533828@qq.com
*/
@Controller
@RequestMapping("test")
public class TestController {
@RequestMapping("test1")
public String test1(Model model){
System.out.println("-------------2-------------------");
int i = 1 / 0;
model.addAttribute("name","Adair");
// SpringMVC自动将request作用域和返回值封装为ModelAndView
return "index";
}
@RequestMapping("test2")
public String test2(){
System.out.println("-------------2-------------------");
return "index";
}
}
如图所示:
4.编写error.jsp的代码如下:
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
<title>登录页面</title>
<meta charset="UTF-8">
</head>
<body>
异常信息:${param.massage}
<h1>当前网络环境较差,请刷新重试!<a href="">刷新</a> </h1>
</body>
</html>
如图所示:
5.通过浏览器访问:http://localhost:8080/test/test1,跳转到如图所示:
3 父子容器问题
如图所示: