文章借鉴:https://blog.csdn.net/Jintao_Ma/article/details/52972482
1、概念
springmvc拦截器是基于servlet的Filter实现的,关于web端几大容器的执行顺序为监听器->过滤器->拦截器->Controller。
context-param:就是一些需要初始化的配置,放入context-param中,从而被监听器(这里特指org.springframework.web.context.ContextLoaderListener)监听,然后加载;
监听器(listener):就是对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化;
过滤器(filter):就是对请求起到过滤的作用,它在监听器之后,作用在servlet之前,对请求进行过滤;(如果过滤所有请求可以用过滤器)。
servlet:就是对request和response进行处理的容器,它在filter之后执行,servlet其中的一部分就是controller层(标记为servlet_2),还包括渲染视图层(标记为servlet_3)和进入controller之前系统的一些处理部分(servlet_1),另外我们把servlet开始的时刻标记为servlet_0,servlet结束的时刻标记为servlet_4。
拦截器(interceptor):就是对请求和返回进行拦截(拦截器只是配置允许的Controller进行拦截),它作用在servlet的内部,具体来说有三个地方:
1)servlet_1和servlet_2之间,即请求还没有到controller层
2)servlet_2和servlet_3之间,即请求走出controller层次,还没有到渲染时图层
3)servlet_3和servlet_4之间,即结束视图渲染,但是还没有到servlet的结束
它们之间的关系,可以用一张图来表示:
2、web端几大容器的使用原则
项目中的有些功能,使用过滤器可以实现,使用拦截器也可以实现,比如判断用户是否登录,既可以用过滤器,也可以用拦截器,用哪一个才是合理的呢?那么如果有一个原则,使用起来就会更加合理。实际上的使用原则:
把整个项目的流程比作一条河,那么监听器的作用就是能够听到河流里的所有声音,过滤器就是能够过滤出其中的鱼,而拦截器则是拦截其中的部分鱼,并且作标记。所以当需要监听到项目中的一些信息,并且不需要对流程做更改时,用监听器;当需要过滤掉其中的部分信息,只留一部分时,就用过滤器;当需要对其流程进行更改,做相关的记录时用拦截器。(过滤器和拦截器本身不应该改变原有Controller的业务逻辑)
3、拦截器实现登录过滤
<1>、首先写一个登录进入登录页面
//进入登录页面 @RequestMapping("/login") public String login(CrsUser user,HttpServletRequest request){ System.out.println("进入登录页面"); return "public/login"; }
<2>、登录验证Controller
/** * 登录控制层 * @param carUser 用户实体对象 * @param request 请求 * @param response 响应 * @return */ @RequestMapping("/Check") public String loginCkeck(CrsUser user,HttpServletRequest request,HttpServletResponse response,Model model){ if(null == user.getPassword() || user.getPassword().equals("")&& null == user.getUserName() || user.getUserName().equals("")){ model.addAttribute("error",0); model.addAttribute("Message","用户名或密码不能为空!"); return "public/login"; }else{ //用户登录密码检测 CrsUser users = loginService.getUser(user); if(!StringUtils.isNullOrEmpty(users)){ if(users.getRole().equals("1")){//管理员 request.getSession().setAttribute("name", user.getUserName()); return "admin/adminIndex"; } if(users.getRole().equals("2")){//普通客户 request.getSession().setAttribute("name", user.getUserName()); return "customer/custIndex"; } if(users.getRole().equals("3")){//用户 model.addAttribute("error",0); model.addAttribute("Message","该用户已停用,如要重新启用请联系管理员"); return "public/login"; } return "public/login"; }else{ model.addAttribute("error",0); model.addAttribute("Message","用户名或密码错误,请重新输入"); return "public/login"; } } }
<3>、登录拦截器
package com.rthl.as.interceptor; import java.util.Arrays; import java.util.List; 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; public class LoginInterceptor implements HandlerInterceptor{ @Override public void afterCompletion(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Object obj, Exception exception) throws Exception { System.out.println("afterCompletion方法开始执行"); } @Override public void postHandle(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Object obj, ModelAndView modelandview) throws Exception { System.out.println("postHandle开始执行"); } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception { //方式一 不拦截的请求(项目名后边的请求路径)request.getRequestURI()(包含项目名的请求路径) String url= request.getServletPath(); //不需要拦截的url列表 List<String> uncheckedUrls = Arrays.asList("/login","/Check","/loginOut","/register","/saveRegister"); if(uncheckedUrls.contains(url)){ return true; } //获取session HttpSession session = request.getSession(); //获取session中设置的值 String username = (String) session.getAttribute("name"); if(null != username && !"".equals(username)){ return true; } //不符合条件跳转登录页面 request.getRequestDispatcher("/login").forward(request, response); return false; } }
<4>、在配置文件(springmvc-servlet.xml)中配置拦截器
<!-- 登录拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.rthl.as.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>然后启动项目进行访问,实现登录过滤功能