方法拦截器_SpringMVC学习——拦截器Intercepter

233c0146cd3ad696ac184b10c2708c75.png

拦截器功能类似于Filter, 但是比Filter的功能更细致. 拦截器是基于AOP实现.

提供了两种方案:

> 实现接口, HandlerInterceptor

> 继承父类, HandlerInterceptorAdapter

拦截器可以在我们访问Controller方法的时候,进行拦截,符合条件了才让通过,否则不让通过

9a79fb74402f55b31ebf61605e7f5ee0.png

登录验证拦截器:

344d2483045515ad150206a8956c75ff.png

有3个方法需要实现:

1、preHandle方法在进入控制器方法前被调用,通常用于控制器方法调用前的验证操作,例如:登录操作,返回值是一个布尔类型的值,为true才让访问控制器方法,否则不让访问

38a0bb1065d1037ccd27aab73e4f31aa.png

2、postHandle方法,在控制器方法执行结束,有返回值,并且在进入页面之前调用该方法

8772bbaa0d6890c4054cb99f54bbc994.png

这里的modelAndView封装了控制器方法的返回值,我们在这里也可以进行返回结果的处理,例如:游戏中骂人的字变成******了

7f208bcfe3bcee23218e4a456321fd04.png

3、afterCompletion方法,流程结束后执行,通常用于统一异常处理

1365dccda375280f1240487a258f33dd.png

这里用以拦截没有登录就访问主页面信息:

package com.chenpeng.interceptor;

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


import com.chenpeng.pojo.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;



/**
 * 登录验证拦截器
 * 
 * @author chenpeng
 *
 */
public class LoginInterceptor implements HandlerInterceptor {

	/**
	 * 在进入控制器方法前被调用
	 * 通常用于控制器方法调用前的验证操作, 例如: 登录验证
	 * 
	 * @param handle - 代表要调用的控制器方法对象
	 * @return 布尔值, true表示可以继续访问, false表示停止访问, 不能继续访问时, 建议给出响应
	 * 	或者可以进行页面的跳转
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) throws Exception {
		System.out.println("LoginInterceptor.preHandle(1)");
		User user = (User) request.getSession().getAttribute("user");
		if(user == null) {
			request.getSession().setAttribute("msg", "请先登录再访问!");
			response.sendRedirect(request.getContextPath() + "/index.jsp");
			return false;
		}
		return true;
	}

	/**
	 * 在控制器方法执行结束, 有返回值后, 并且在进入页面之前调用该方法
	 * 
	 * @param modelAndView - 代表控制器方法的返回内容
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)
			throws Exception {
		System.out.println("LoginInterceptor.postHandle(3)");
	}

	/**
	 * 流程结束后执行, 通常用于统一异常处理
	 * @param ex - 异常对象
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)
			throws Exception {
		System.out.println("LoginInterceptor.afterCompletion(5)");
	}

}

需要在SpringMVC的配置文件中配置:

b64b377f6e49b333c739d2856a6f5fec.png

继承父类HandlerInterceptorAdapter,日志拦截器

4388eb84db9743e3c61c77ad1d65ac0e.png

它是一个抽象类,但是没有抽象方法

package com.chenpeng.interceptor;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 日志拦截器
 * 
 * @author chenpeng
 *
 */
public class LoggerInterceprtor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("[日志拦截器]: " + handler + " 要被调用了...");
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("[日志拦截器]: " + handler + " 调用结束, modelAndView: " + modelAndView);
	}
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("[日志拦截器]: " + handler + " 流程结束.");
	}
}

我们可以在Controller方法执行前调用preHandle方法,方法执行之后调用postHandle方法,之后调用afterCompletion方法

配置文件

ef57b288b789e42253f6fb5c84b42c6a.png

那么问题来了?

1. 两个拦截器的时候, 先执行哪个有谁决定?

谁先配置的,就先执行

当我们点击分页查询的时候:先执行了先配置的日志拦截器然后执行了登录拦截器

控制台效果:

[日志拦截器]: public java.lang.String com.chenpeng.controller.UserController.selByPage(int,int,org.springframework.ui.Model) 要被调用了...
LoginInterceptor.preHandle(1)
- ==>  Preparing: SELECT count(0) FROM t_user 
- ==> Parameters: 
- <==    Columns: count(0)
- <==        Row: 24
- <==      Total: 1
- ==>  Preparing: select id, login_name, login_pswd, name, birthday, reg_time from t_user LIMIT ?, ? 
- ==> Parameters: 3(Integer), 3(Integer)
- <==    Columns: id, login_name, login_pswd, name, birthday, reg_time
- <==        Row: 4, zhouxingchi, 123, 周星驰, 1994-10-25, 2018-11-15 21:02:00.0
- <==        Row: 5, zhourunfa, 123, 周润发, 1994-10-25, 2018-11-15 21:02:00.0
- <==        Row: 6, zhangguorong, 123, 张国荣, 1994-10-25, 2018-11-16 21:02:00.0
- <==      Total: 3
LoginInterceptor.postHandle(3)
[日志拦截器]: public java.lang.String com.chenpeng.controller.UserController.selByPage(int,int,org.springframework.ui.Model) 调用结束, mode
LoginInterceptor.afterCompletion(5)
[日志拦截器]: public java.lang.String com.chenpeng.controller.UserController.selByPage(int,int,org.springframework.ui.Model) 流程结束.

2. 两个拦截器有6个方法, 6个方法的执行顺序?

遵循栈的规则,先进后出的顺序

3. 多个拦截器的执行流程

多个拦截器通常被称为拦截器栈, 先配置的拦截器先执行. ,如果我们先配置的是登录拦截器,则为:下图

f3ea8e6ddee66181bdf91417fda024c5.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值