在实际项目中,拦截器的使用是非常普遍的,例如在购物网站中通过拦截器可以拦截未登录的用户,禁止其购买商品,或者使用它来验证已登录用户是否有相应的操作权限等,Spring MVC提供了拦截器功能,通过配置即可对请求进行拦截处理。
拦截器的定义:
要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。一种是通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义;另一种是通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。
以实现HandlerInterceptor接口的定义方式为例,自定义拦截器类的代码如下所示:
复制代码
public class LoginInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
}
复制代码
关于这三个方法的具体描述如下:
(1)preHandler()方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。
(2)postHandle()方法:该方法会在控制器方法调用之后,其解析试图之前执行。可以通过此方法对请求域中的模型和试图做出进一步的修改。
(3)afterCompletion()方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过次方法实现一些资料清理、记录日志信息等工作。
拦截器的配置:
要使自定义的拦截器类生效,还需要在Spring MVC的配置文件中进行配置,配置代码如下:
复制代码
复制代码
在上述代码中,
元素用于配置一组拦截器,其子元素中定义是全局拦截器,它会拦截所有的请求;而元素中定义的是指定路径的拦截器,它会对指定路径下的请求生效。元素的子元素用于配置拦截器作用的路径,该路径在其属性path中定义。如上述代码path的属性值“/**”表示拦截所有路径,“/hello”表示拦截所有以“/hello”结尾的路径。如果在请求路径中包含不需要拦截的内容,还可以通过元素进行配置。
需要注意的是,中的子元素必须按照上述代码的配置顺序进行编写,即 -> -> 的顺序,否则文件会报错。
单个拦截器的执行流程如下:
程序首先会执行拦截器类中的preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行;在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应;在DispatcherServlet处理完请求后,才会执行afterCompletion()方法。
多个拦截器的执行流程:
当多个拦截器同时工作时,它们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。
假设有两个拦截器Interceptor1和interceptor2,并且在配置文件中,Interceptor1拦截器配置在前。
接下来我们通过拦截器来完成一个用户登录权限验证的案例。
本案例中,只有登陆后的用户才能访问系统中的主页面,如果没有登录系统而直接访问主页面,则拦截器会将请求拦截,并转发到登录页面,同时在登录页面中给出提示信息。如果用户名或密码错误,也会在登录页面给出相应的提示信息。当已登录的用户在系统主页中单击“退出”链接时,系统同样会回到登录页面。
(1)在eclipse中新建一个动态web项目,在lib目录下导入相关Sping MVC的JAE包,搭建Spring MVC的环境。
(2)在src目录下,创建一个com.neuedu.pojo包,并在包中创建User类。在User类中,代码如下:
复制代码
package com.neuedu.pojo;
public class User {
private Integer id;//id
private String username;//用户名
private String password;//密码
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
}
复制代码
(3)在src目录下,新建com.neuedu.controller包,创建控制器类UserController,并在该类中定义向主页跳转、向登录页面跳转、执行用户登录等操作的方法,代码如下:
复制代码
package com.neuedu.controller;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.neuedu.pojo.User;
@Controller
public class UserController {
/*
* 向用户登录页面跳转
* */
@RequestMapping(value="/login",method=RequestMethod.GET)
public String toLogin() {
return "login";
}
/*
* 用户登录
* */
@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(User user,Model model,HttpSession session) {
//获取用户名和密码
String username = user.getUsername();
String password = user.getPassword();
//此处模拟从数据库中获取用户名和密码后进行判断
if(username != null && username.equals("wangyifei")
&& password != null && password.equals("123456")) {
//将用户对象添加到Session
session.setAttribute("USER_SESSION", user);
//向主页面跳转
return "main";
}
model.addAttribute("msg","用户名或密码错误,请重新登录!");
return "login";
}
/*
* 向用户主页面跳转
* */
@RequestMapping(value="/main")
public String toMain() {
return "main";
}
/*
* 退出登录
* */
@RequestMapping(value="/logout")
public String logout(HttpSession session) {
//清除Session
session.invalidate();
//向登录页面跳转
return "login";
}
}
复制代码
(4)在src目录下,新建com.neuedu.interceptor包,创建拦截器类LoginInterceptor,代码如下:
复制代码
package com.neuedu.interceptor;
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;
import com.neuedu.pojo.User;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取请求的URL
String url = request.getRequestURI();
//URL:除了login.jsp是可以公开访问的,其他的URL都进行拦截控制
if(url.indexOf("/login")>=0) {
return true;
}
//获取Session
HttpSession session = request.getSession();
User user = (User)session.getAttribute("USER_SESSION");
//判断Session中是否有用户数据,如果有,则返回true,继续向下执行
if(user != null) {
return true;
}
//不符合条件的给出提示信息,并转发到登录页面
request.setAttribute("msg","您还没有登录,请先登录!");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
}
复制代码
(5)配置文件springmvc-config.xml代码如下所示:
复制代码
复制代码
(6)在WEB-INF目录下新建jsp文件夹中,创建一个系统主页面main.jsp,代码如下:
复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
当前用户:${USER_SESSION.username }
退出
复制代码
(7)在jsp文件夹创建一个login.jsp,在页面中编写一个用于实现登录操作的form表单,代码如下:
复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
${msg }
复制代码
(8)web.xml文件配置代码如下:
复制代码
interceptor
index.html
hello
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-config.xml
1
hello
*.action
复制代码
(9)整个项目目录结构如下:
(10)将项目发布到Tomcat服务器并启动,在浏览器中访问地址 http://localhost:8080/interceptor/main.action,效果如下:
未登录,不能直接访问主页面!
输入错误用户名“java”和密码“123456”,给出提示!
输入正确用户名“wangyifei”和密码“123456”,成功进入主页面!https://www.cnblogs.com/yifeiyaoshangtian/p/9528264.html