文章借鉴: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>
然后启动项目进行访问,实现登录过滤功能