1.5(Spring MVC学习笔记) 拦截器(Interceptor)
一、拦截器
1.1拦截器简介
Spring中的拦截器类似Servlet中的过滤器(Filter),主要用于拦截用户请求,
并进行一定的处理操作(如验证权限、记录日志、设置编码方式等)。
1.2拦截器实现
SpringMVC实现拦截器主要通过实现HandlerInterceptor接口,
或者是继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来实现。
HandlerInterceptor接口中有三个方法:
public boolean preHanlder(){...}:该方法在执行控制类方法之前执行,
如果该方法返回值为false后续执行终止(拦截器,处理器,控制类都终止)。
public void postHandler(){...}:该方法在控制类中方法执之后执行。
public void afterCompletion(){...}:该方法最后执行,在视图渲染结束后执行。
例如用户发送一个请求执行控制类中某个方法,首先执行preHanlder方法。
然后判断preHandler方法的返回值为true则继续执行,为false则中止。
接着当控制类中方法执行完后,执行拦截器中的postHandler方法。
接着执行后续的视图解析器,渲染视图,最后执行拦截器中的afterCompletion().
1.3拦截器配置
定义好拦截器类后,在xml文件中配置即可。
配置元素:
<mvc:interceptors>:所有拦截器都配置在该元素下。
子元素为<mvc:interceptors>,一个子元素代表一个拦截器,
可配置多个
<mvc:interceptor>:配置单个拦截器
<mvc:mapping>:指定拦截器需要拦截的路径。
<mvc:exclude-mapping>:指定拦截器不需要拦截的路径。
path属性作用于<mvc:mapping><mvc:exclude-mapping>,
用于指定拦截路径。
<bean>:代表具体拦截器的实现类。
在<mvc:interceptors>中配置<bena>,则该拦截器为全局拦截器会拦截所有请求。
在<mvc:interceptor>元素中配置,为拦截指定的路径。
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置在interceptors中为全局拦截器 -->
<bean class = "com.springmvc.interceptor.CustomInterceptor"/>
<!-- 单个拦截器 -->
<mvc:interceptor>
<!-- 配置拦截内容,拦截所有内容 -->
<mvc:mapping path="/**"/>
<!-- 配置不拦截内容 -->
<mvc:exclude-mapping path=""/>
<!-- 对应的拦截器 -->
<bean class = "xxx.xxx.xxx"/>
</mvc:interceptor>
</mvc:interceptors>
下面看一个拦截器的例子
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<display-name>SpringMVC</display-name> <!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class >
org.springframework.web.servlet.DispatcherServlet
</servlet-class> <!-- 初始化时加载配置文件,该配置文件是在src目录下创建的。 -->
<!-- <init-param> 该选项不配置,则做会自动寻找WEB-INF下名为springmvc-servlet.xml的文件。-->
<!-- <param-name>contextConfigLocation</param-name>-->
<!-- <param-value>classpath:springmvc-config.xml</param-value>-->
<!--</init-param>-->
<!-- 当前servlet与容器一起加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 所有请求都会被前端控制器拦截-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
CustomInterceptor.java(拦截器)
import java.io.PrintStream; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class CustomInterceptor implements HandlerInterceptor{
//在HadlerAdapter之前执行(简单的看就是在访问控制类之前执行)
PrintStream out = System.out;
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
// TODO Auto-generated method stub
out.println("preHandle...");
return true;
} //在控制器方法调用后,视图解析器之前执行。
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub
out.println("postHandle...");
} //最后执行,
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
out.println("afterCompletionHandle...");
} }
springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 开启扫描 -->
<context:component-scan base-package = "com.springmvc.*"></context:component-scan>
<!-- testJson -->
<!-- 配置注解驱动 -->
<mvc:annotation-driven/>
<!-- 指定某些文件不被前端控制器拦截,直接访问静态文件。 -->
<!-- 设置视图处理器及其前缀后缀 -->
<bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value = "/WEB-INF/jsp/"></property>
<property name="suffix" value = ".jsp"></property>
</bean> <!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置在interceptors中为全局拦截器 -->
<bean class = "com.springmvc.interceptor.CustomInterceptor"/>
</mvc:interceptors> </beans>
控制类
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class InterceptorsControl {
@RequestMapping("/testInterceptor")
public String handler() {
System.out.println("handler");
return "success";
}
}
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.springmvc.binderList.*" %>
<!DOCTYPE html> <html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
success <br/> </body>
</html>


1.4多个过滤器
多个过滤器配置与上述类似,只是在<mvc:interceptors>中配置多个<mvc:interceptor>即可。
关键是多个过滤器的执行顺序。

假设有拦截器1~n,
执行顺序为: pre(1) pre(2)....pre(n) post(n) post(n-1)....post(1) after(n)after(n-1)...after(1)
先将上述CustomInterceptor中的所有打印语句中添加一个数字1。
System.out.println("perHadler1")
在将Customlnterceptor.java文件复制,并改名为CustomInterceptor2.java
并将其中数字1改为2.
修改springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 开启扫描 -->
<context:component-scan base-package = "com.springmvc.*"></context:component-scan>
<!-- testJson -->
<!-- 配置注解驱动 -->
<mvc:annotation-driven/> <bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value = "/WEB-INF/jsp/"></property>
<property name="suffix" value = ".jsp"></property>
</bean> <!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 拦截器1 -->
<mvc:interceptor>
<mvc:mapping path="/testInterceptor"/>
<bean class = "com.springmvc.interceptor.CustomInterceptor"/>
</mvc:interceptor>
<!-- 拦截器2 -->
<mvc:interceptor>
<mvc:mapping path="/testInterceptor"/>
<bean class = "com.springmvc.interceptor.CustomInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors> </beans>

二、拦截器登录注册案例
User.java(POJO类)
public class User {
private int id;
private String userName;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Validate.java(拦截器)
拦截所有请求进行判断,
如果是去往登录页面或是登录验证放行,
如果已登录放行,
其它则跳转到登录页面。
未登录情况下无法任何资源页面,只能访问登录页面
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class Validate implements HandlerInterceptor{ @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub } @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub } @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("into interceptor");
String url = request.getRequestURI();
HttpSession session = request.getSession();
//去往登录页面放行 或者是登录验证放行
if(url.indexOf("/login") > 0 || url.indexOf("/checkLogin") > 0)
return true;
//已登录放行
if(session.getAttribute("user") != null)
return true;
//既不是去登录页面,同时未登录则跳转到登录页面,并提升未登录,请登录。
request.setAttribute("msg", "未登录,请登录");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
} }
UserController.java(控制类)
import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class UserController {
//登录验证
@RequestMapping("/checkLogin")
public String checkLogin(User user, Model model, HttpSession session) {
String userName = user.getUserName();
String password = user.getPassword();
//模拟数据查询
if(userName != null && password != null &&
userName.equals("hcf") && password.equals("123456")) {
//登录成功后设置session用于记录登录状态
session.setAttribute("user", user);
return "main";
}
model.addAttribute("msg", "用户名或密码错误或为空!");
return "login";
} //跳转main
@RequestMapping("/main")
public String toMain() {
return "main";
} //跳转登录页面
@RequestMapping("/login")
public String login() {
return "login";
} //注销用户,即销毁session
@RequestMapping("/loginOut")
public String loginOut(HttpSession session) {
session.invalidate();
return "login";
}
}
login.jsp (登录页面)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg}<br> <!--表达提交后进行登录验证-->
<form action = "${pageContext.request.contextPath}/checkLogin" method = "post">
用户名:<input type = "text" name = "userName"/><br/> <!--name属性的值要和POJO类中属性名相同才可自动填充-->
密 码:<input type = "text" name = "password"/><br/>
<input type = "submit" value = "登录"/>
</form>
</body>
</html>
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body> weclome:<br>
${sessionScope.user.userName}
<a href = "${pageContext.request.contextPath}/loginOut">注销</a> </body>
</html>
用户请求访问main.jsp,会被拦截,判断是否登录。
如果登录则放行,执行控制类中的跳转主页方法。
如果未登录则设置msg值,并跳转登录页面。
用户访问登录页面直接放行。
登录页面提交表单后也会被拦截,拦截器判断为登录检查放行。
控制类中会对用户名及密码进行检查。
密码正确设置session保持登录状态,并跳转到main.jsp.
密码错误则设置msg值,并跳转到登录页面。

1.5(Spring MVC学习笔记) 拦截器(Interceptor)的更多相关文章
- struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo
理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...
- Spring MVC 学习 之 - 拦截器
public class GlobalInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletR ...
- Spring MVC中的拦截器Interceptor
谈谈spring中的拦截器 在web开发中,拦截器是经常用到的功能.它可以帮我们验证是否登陆.预先设置数据以及统计方法的执行效率等等.今天就来详细的谈一下spring中的拦截器.spring中拦截器主 ...
- spring MVC 学习(四)---拦截器,视图解析器
1.接口HandlerInterceptor 该接口包含3个方法,分别是preHandle,postHandle,afterCompletion,分别代表着执行前,执行后,执行完成要执行的方法,其中p ...
- Spring MVC 学习笔记一 HelloWorld
Spring MVC 学习笔记一 HelloWorld Spring MVC 的使用可以按照以下步骤进行(使用Eclipse): 加入JAR包 在web.xml中配置DispatcherServlet ...
- Spring MVC 学习笔记1 - First Helloworld by Eclipse【& - java web 开发Tips集锦】
Spring MVC 学习笔记1 - First Helloworld by Eclipse reference:http://www.gontu.org 1. 下载 Spring freamwork ...
- spring mvc中的拦截器小结 .
在spring mvc中,拦截器其实比较简单了,下面简单小结并demo下. preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Control ...
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...
- Spring MVC 学习笔记11 —— 后端返回json格式数据
Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...
随机推荐
- 7月16号day8总结
今天学习过程和小结 1.列举Linux常用命令 shutdown now Linux关机 rebot重启 mkdir mkdir -p递归创建 vi/touth filename rm -r file ...
- 微信小程序基础知识
一.基本目录结构 app.js 定义app入口 app.json 定义页面配置 index.js 页面中的事件和监听 index.wxml 定义布局文件 1.app.json配置基本信息 { “pag ...
- JAVA Eclipse 教程
http://www.runoob.com/eclipse/eclipse-tutorial.html
- 使用maven构建第一个web项目
在eclipse中,正常创建maven项目后,发现在index.jsp中会报错,此时在pom.xml中加入如下依赖关系即可 <dependency> <groupId>java ...
- 编译cuda Examples 时出现错误:/bin/ld cannot find -lglut
编译cuda Examples 时出现错误:/bin/ld cannot find -lglut ,可以先找找是否缺少库,有时候可能是symbolic link不正确,没有链接到正确位置,导致找不到库 ...
- jQuery 入门笔记1
jQuery是一个兼容多浏览器的javascript框架,核心理念是write less,do more(写得更少,做得更多). 1:jQuery使用 <script type="te ...
- linux常用命令 ps
linux常用命令 ps Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些线程的快照,就是执行ps命令的那个时刻的那些进程 ...
- 解决 org.aspectj.weaver.ResolvedType$Array cannot be cast to org.aspectj.weaver.ReferenceType
参考:http://www.cnblogs.com/qgc88/p/3283217.html 解决方法: 删除aspectjweaver.jar和aspect.jar 加入aspectjweaver- ...
- 使用graphql和apollo client构建react web应用
graphql是一种用于 API 的查询语言(摘自官网). 我们为什么要用graphql? 相信大家在开发web应用的时候常常会遇到以下这些问题:后端更新了接口却没有通知前端,从而导致各种报错:后端修 ...
- OfficeAddin基础
运行的机器制