Spring MVC拦截器概述、执行流程和应用例子

1 拦截器概述

  Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),主要用于拦截用户请求并作相应的处理。拦截器可以进行全限验证、记录请求信息的日志、判断用户是否登录等。

1.1 拦截器的定义

  1. 通过实现HandlerInterceptor接口,或者继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。
  2. 通过实现WebRequestInterceptor接口,或者继承WebRequestInterceptor接口的实现类来定义。

以实现HandlerInterceptor接口方式为例:

1.2 拦截器的配置

  在Spring MVC的配置文件中进行配置:

2 拦截器的执行流程

  在程序运行过程中,拦截器的执行是由顺序的,这个顺序和拦截器的定义顺序有关。

2.1 单个拦截器执行顺序

2.1.1 举个例子

  • springmvc-config.xml中配置拦截器
<!-- 拦截器配置 -->
<mvc:interceptors>
	<bean class="cn.edu.ujn.ch15.interceptor.CustomerInterceptor"></bean>
</mvc:interceptors>
  • HelloController.java
package cn.edu.ujn.ch15.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
	@RequestMapping("/hello")
	public String hello() {
		System.out.println("hello!");
		return "success";
	}

	@RequestMapping("/find")
	public String find() {
		System.out.println("Find!");
		return "success";

	}
}
  • CustomerInterceptor.java
package cn.edu.ujn.ch15.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class CustomerInterceptor implements HandlerInterceptor {

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CustomerInterceptor--preHandle");
		return true;
	}

	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CustomerInterceptor--postHandle");
	}

	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CustomerInterceptor--afterCompletion");
	}

}

  • 测试结果:

2.2 多个拦截器执行顺序

2.2.1 举个例子

  • springmvc-config.xml中配置拦截器:
	<!-- 拦截器配置 -->
	<mvc:interceptors>
		<bean class="cn.edu.ujn.ch15.interceptor.CustomerInterceptor"></bean>
		<mvc:interceptor>
			<mvc:mapping path="/hello" />
			<bean class="cn.edu.ujn.ch15.interceptor.Interceptor2"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

  • HelloController.java
package cn.edu.ujn.ch15.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
	@RequestMapping("/hello")
	public String hello() {
		System.out.println("hello!");
		return "success";
	}
	@RequestMapping("/find")
	public String find() {
		System.out.println("Find!");
		return "success";
	}
}
  • 拦截器1(CustomerInterceptor.java)
package cn.edu.ujn.ch15.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class CustomerInterceptor implements HandlerInterceptor {

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CustomerInterceptor--preHandle");
		return true;
	}

	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CustomerInterceptor--postHandle");
	}

	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CustomerInterceptor--afterCompletion");
	}
}
  • 拦截器2(Interceptor2.java)
package cn.edu.ujn.ch15.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class Interceptor2 implements HandlerInterceptor {
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor2--preHandle");
		return true;
	}
	
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor2--postHandle");
	}
	
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor2--afterCompletion");
	}
}
  • 测试结果

3 应用案例-实现用户登录权限验证

3.1 案例说明

  • 登录验证:只有登录成功后的用户才可以访问系统中的主页面
  • 未登录:拦截器会将请求拦截,并转发到登录页面,同时在登录页面中给出提示信息
  • 登录未成功:在登录页面给出相应的提示信息
  • 退出登录:系统同样会回到登录页面

3.2 流程图

3.3 实现代码

3.3.1 User.java

package cn.edu.ujn.ch15.model;

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;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
	}

}

3.3.2 UserController.java

package cn.edu.ujn.ch15.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 cn.edu.ujn.ch15.model.User;

@Controller
public class UserController {
	// 以GET方式请求
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String toLogin() {
		return "login";
	}

	// 以POST方式请求
	// User接受页面传递来的用户名和密码
	// Model向页面返回错误信息的
	// 登录成功后需要向session中写入User对象
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login(User user, Model model, HttpSession session) {
		// 用户名为A
		if ("A".equals(user.getUsername())) {
			session.setAttribute("USER_SESSION", user);
			return "redirect:main";
		}
		model.addAttribute("msg", "用户名或密码错误,请重新登录!");
		return "login";
	}

	@RequestMapping("/main")
	public String toMain() {
		return "main";
	}

	// 退出则清空session
	@RequestMapping("/logout")
	public String logout(HttpSession session) {
		// 清空session
		session.invalidate();
		return "redirect:login";
	}
}

3.3.3 LoginInterceptor.java

package cn.edu.ujn.ch15.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;

import cn.edu.ujn.ch15.model.User;

public class LoginInterceptor implements HandlerInterceptor {
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// login这个请求不要拦截,不然没办法登录
		String url = request.getRequestURI();
		// 判断url中是否有“login”
		if (url.indexOf("/login") >= 0)
			return true;
		HttpSession session = request.getSession();
		// 获取User对象
		User user = (User) session.getAttribute("USER_SESSION");
		// 判断user是否为空
		if (user != null)
			return true;
		// 为空就显示提示信息
		request.setAttribute("msg", "被拦截,您还没有登录,不能访问页面!");
		// 转发到login.jsp页面
		request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
		return false;
	}
}

3.3.4 配置拦截器(springmvc-config.xml)

<mvc:interceptor>
	<!-- 所有请求都拦截 -->
	<mvc:mapping path="/**" />
	<bean class="cn.edu.ujn.ch15.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
	

3.3.5 login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录</title>
</head>
<body>
    ${msg}
	<form action="${pageContext.request.contextPath }/login" 
            method="POST">
		用户名:<input type="text" name="username"/><br />&nbsp;&nbsp;&nbsp;码:
                 <input type="password" name="password"/><br />
		<input type="submit" value="登录" />
	</form>
</body>
</html>

3.3.6 main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>系统主页</title>
</head>
<body>
    当前用户:${USER_SESSION.username}  
    <a href="${pageContext.request.contextPath }/logout">退出</a>  
</body>
</html>

3.4 测试结果

  • 登录不成功,无法访问main.jsp页面
  • 登录成功

声明:
若本人发布的作品涉及版权或存在其他问题,请联系我删除。
谢谢浏览!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值