拦截器(interceptor)

本文介绍了SpringMVC中的处理器拦截器,它与Servlet过滤器的区别以及如何自定义拦截器。拦截器按照预定义的顺序执行,用于方法的预处理和后处理,例如在用户访问资源前检查是否已登录。自定义拦截器需实现HandlerInterceptor接口,并在配置文件中注册。文章还提供了一个简单的用户登录验证的拦截器案例。
摘要由CSDN通过智能技术生成

一、拦截器介绍和作用

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。用户可以自己定义一些拦截器来实现特定的功能。谈到拦截器,还要向大家提一个词—拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段是时,拦截器链中拦截器就会按其之前定义的顺序被调用。

二、拦截器与过滤器的区别

过滤器是Servlet规范中的一部分,任何java web工程都可以使用。拦截器是 SpringMVC 框架自己的,只有使用了SpringMVC框架的工程才能用。过滤器在web.xml中的 url-pattern 标签中配置了 /* 之后,可以对所有要访问的资源拦截。

我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。

三、自定义拦截器的步骤

(一)实现HandlerInterceptor接口

public class MyIntercepter implements HandlerInterceptor {
    
	/**
	* 控制层执行器方法前的拦截器
	* @param request
	* @param response
	* @param handler
	* @return
	* @throws Exception
	*/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("我是控制层执行器方法前的拦截器");
        //校验用户是否登录
        HttpSession session = request.getSession();
        String pname=(String)session.getAttribute("pname");
        if(pname!=null){
            //当前用户已经登录,放行
            return true;
        }else{
            //当前用户未登录,拦截跳转到登录页面
			request.getRequestDispatcher("/login.jsp").forward(request,response);
            return false;
        }
        //返回true表示继续执行控制层执行器方法,返回false表示方法结束,不会执行控制层执行器方法
}
    
    
	/**
	* 控制层方法返回时拦截器
	* @param request
	* @param response
	* @param handler
	* @param modelAndView
	* @throws Exception
	*/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("我是控制层执行器方法返回时拦截器");
    }
    
    
	/**
	* 控制层方法结束后的拦截器
	* @param request
	* @param response
	* @param handler
	* @param ex
	* @throws Exception
	*/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponseresponse, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("我是控制层执行器方法结束后的拦截器");
    }
}

(二)配置拦截器

<!--springMVC配置文件中注册拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/><!--用于指定拦截的url-->
        <mvc:exclude-mapping path="/file/login"/><!--用于指定排除的url-->
        <bean class="com.offcn.util.MyIntercepter"></bean>
    </mvc:interceptor>
</mvc:interceptors>

四、拦截器的注意事项

(一)拦截器的放行

拦截器中的放行指的是:如果有下一个拦截器就执行下一个,如果该拦截器处于拦截器链的最后一个,则执行控制器中的方法。

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    //方法返回true表示继续执行控制层执行器方法,返回false表示方法结束,不会执行控制层执行器方法。

(二)拦截器中方法的说明

定义拦截器需要实现HandlerInterceptor接口,该接口中有三个方法:

  • preHandle()方法

    控制层执行器方法前的拦截器(该方法时在控制层执行器方法前调用,当该方法返回结果为true则继续调用下一个拦截器,如果已经是最后一个拦截器,则调用控制层中的执行器方法;当该方法返回结果为false,则不会继续执行控制层执行器中的方法)

  • postHandle()方法

    控制层方法返回时拦截器(该方法是控制层执行器方法执行之后,由DispatcherServlet在将结果响应给浏览器前调用的方法)

  • afterCompletion()方法

    控制层方法结束后的拦截器(该方法在请求业务处理执行完全结束之后由DispatcherServlet调用执行)

(三)多个拦截器的执行顺序

  1. 先来顺序执行 所有拦截器的 preHandle方法
  2. 如果任何一个拦截器返回false。直接跳出不执行目标方法
    • 如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle
    • 如果当前拦截器返回为false。直接 倒序执行所有已经执行了的拦截器的 afterCompletion;
  3. 所有拦截器都返回True。执行目标方法
  4. 倒序执行所有拦截器的postHandle方法。
  5. 前面的步骤有任何异常都会直接倒序触发 afterCompletion
  6. 页面成功渲染完成以后,也会倒序触发 afterCompletion

五、拦截器的简单案例(验证用户是否登录)

(一)实现思路分析

1、定义登录页面,并定义请求映射。

2、判断用户名密码是否正确

3、如果正确 向 session 中写入用户信息

4、返回登录成功。

5、拦截用户请求,判断用户是否登录

6、如果用户已经登录。放行

7、如果用户未登录,跳转到登录页面

(二)案例代码

1、登录页面 login.jsp

<html>
<head>
	<title>Title</title>
</head>
<body>
<form action="/file/login" method="post">
	用户名:<input type="text" name="pname">
	密码:<input type="text" name="password">
	<input type="submit" value="登录">
</form>
</body>
</html>

2、控制器实现

@RequestMapping("login")
public String login(String pname, String password, HttpSession session){
	System.out.println("登录校验成功");
	//将登录成功的用户名存放到session中
	session.setAttribute("pname",pname);
	return "main";
}	

3、拦截器实现

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	System.out.println("我是控制层执行器方法前的拦截器");
	//校验用户是否登录
	HttpSession session = request.getSession();
	String pname=(String)session.getAttribute("pname");
	if(pname!=null){
		//当前用户已经登录,放行
		return true;
	}else{
		//当前用户未登录,拦截跳转到登录页面
		request.getRequestDispatcher("/login.jsp").forward(request,response);
		return false;
	}
	//返回true表示继续执行控制层执行器方法,返回false表示方法结束,不会执行控制层执行器方法
}

4、注册拦截器

<mvc:interceptor>
	<mvc:mapping path="/**"/><!--用于指定拦截的 url-->
	<mvc:exclude-mapping path="/file/login"/><!--用于指定排除的 url-->
	<bean class="com.offcn.util.MyIntercepter"></bean>
</mvc:interceptor>
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网底层民工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值