一、拦截器介绍和作用

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>
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐