SpringMVC拦截器
Interceptor
拦截器,是SpringMVC提供用来拦截发送给Controller
层方法请求的拦截器。类似于filter 主要进行记录日志,判断用户是否登录,过滤权限(没有登录就跳转登录之类的)
拦截器和我们所学的过滤器是很相似的,只是范围不一样。
- 过滤器
filter
:是JavaEE提供的用来拦截所有的请求,进行过滤,它主要用于实现编码过滤,进行统一编码,防止乱码。 - 拦截器
interceptor
:主要用来拦截Controller
控制器的方法,一般用于拦截Controller
层,满足条件才放行,主要用于实现权限分配,不满足条件不能访问一些界面(比如登录才能进入)。
【注意】一般请求都是先通过过滤器filter
过滤,才会被拦截器interceptor
处理,决定是否放行,两个过程有任何一个不放行,都不能访问到Controller
层方法。
1. 过滤器和拦截器的大概执行流程【***】
2. 拦截器的三个方法
boolean preHandle()
:在访问controller方法之前执行,返回为true才会去执行Controller方法,返回false,就被拦截了,原路打回(主要做权限控制,有权限才放行)。void postHandle()
:在执行controller方法之后, 执行jsp页面之前执行该方法,可以向作用域中放入数据,影响jsp展示效果,(可以在执行jsp之前做渲染)void afterCompletion
:在jsp页面渲染完成之后执行,(主要用于记录日志,资源释放)
,
【注意小知识点来啦】如果preHadle
返回true,但是没有找到对应的Controller
,是不会执行postHandle
方法哦。
差不多就是这样的模板
public class MyInterceptor implements HandlerInterceptor {
// 在访问controller方法之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//prehandle:访问controller之前执行,返回true 继续访问controller。
System.out.println("\n----------AuthInterceptor 【preHandle】--------------");
return true;//返回false就不再继续执行controller方法
}
// 如果没有controller就不执行postHandle方法
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//posthandle:在执行controller方法之后, 执行jsp之前执行该方法,可以向作用域中放入数据,影响jsp展示效果,(可以执行jsp之前做渲染)
System.out.println("----------AuthInterceptor 【postHandle】-------------- ");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//afterCompletion:在jsp渲染之后执行,用于记录日志,资源释放
System.out.println("----------AuthInterceptor 【afterCompletion】--------------");
//记录日志 向文件里面写日志
String logdir = request.getServletContext().getRealPath("log");//获取服务器记录日志log文件所存放的目录位置 -- tomcat下的真实路径+log目录
//路径不存在就创建
Path logdirPath = Paths.get(logdir);
if(Files.notExists(logdirPath)){
Files.createDirectories(logdirPath);
}
//目录存在就将数据[字符]写入
Path logfile = Paths.get(logdir,"userlog.log");//存放日志的路径+文件名
BufferedWriter writer = new BufferedWriter(new FileWriter(logfile.toFile(),true));//logfile.toFile() paths转换为File类型 true以追加的方式写入
//获取登录用户信息
Users user = (Users)request.getSession().getAttribute("user");
String username = user.getUsername();
//记录user登录时间,存入日志
String message = username+" 登录时间:"+new Date();
writer.write(message+"\r\n");
writer.flush();
writer.close();
}
}
3. 多个拦截器的执行顺序
如果所有拦截器都通过(都不拦截)执行顺序是这样的:
(都执行的话,preHandle
顺序执行,postHandler
逆序执行,最后再afterCompletion
逆序执行)
如果拦截器1拦截(也就是preHandle1
返回false),那么后面的拦截器也不执行,直接原路打回。
如果拦截器3拦截,那么也不执行controller方法,大概是这样的。
4. SpringMVC拦截器的配置
4.1 自定义拦截器,实现HandlerInterceptor
接口
//实现一个接口HandlerInterceptor
public class Demo01Interceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;//放行执行controller
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
4.2 springmvc.xml配置拦截器
配置多个拦截器
<!-- /** 是拦截所有的请求 path="/interceptor"只拦截interceptor路径-->
<mvc:interceptors>
<mvc:interceptor>
<!-- /**拦截所有请求,配置全局拦截器 -->
<mvc:mapping path="/**"/>
<bean class="com.xgf.springmvc.ajax.interceptor.AuthInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- /interceptor 之拦截interceptor该路径 -->
<mvc:mapping path="/interceptor"/>
<bean class="com.xgf.springmvc.ajax.interceptor.AuthInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
5. 案例:用户权限拦截器和日志记录
有些页面只有用户登录才能访问,未登录不能访问。
5.1 案例图解【***】
浏览器进行访问,想去购物车模块/订单模块需要先进行用户登录,用户权限拦截器进行判断用户登录没有,登录成功,放行,可以访问。未登录,拦截,跳转登录界面。
5.2 用户权限拦截器UserAuthInterceptor
作用:判断访问路径,如果访问的是order订单模块或者cart购物车模块.就需要判断用户是否登录,读取session中的用户信息,未登录强制跳转到登入页面,登录就放行,进入相应页面
public class UserAuthInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("UserAuthInterceptor preHandle------------------------");
User user = (User) request.getSession().getAttribute("user");
if(user == null){
//未登录才判断,登录了直接放行
String address = request.getRequestURI();//获取路径
System.out.println("address = "+address);
//是购物车或者订单页面,就直接跳转登录界面
if(address.contains("order")||address.contains("cart")){
//强制到登录页面
response.sendRedirect(request.getContextPath() + "/login.jsp");
//设置为false,不访问controller
return false;
}
}
//其它模块或者已经登录,就直接放行
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("UserAuthInterceptor postHandle------------------------");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("UserAuthInterceptor afterCompletion------------------------");
//记录日志 向文件里面写日志
String logdir = request.getServletContext().getRealPath("log");//获取服务器记录日志log文件所存放的目录位置 -- tomcat下的真实路径+log目录
//路径不存在就创建
Path logdirPath = Paths.get(logdir);
if(Files.notExists(logdirPath)){
Files.createDirectories(logdirPath);
}
//目录存在就将数据[字符]写入
Path logfile = Paths.get(logdir,"userlog.log");//存放日志的路径+文件名
BufferedWriter writer = new BufferedWriter(new FileWriter(logfile.toFile(),true));//logfile.toFile() paths转换为File类型 true以追加的方式写入
//获取登录用户信息
Users user = (Users)request.getSession().getAttribute("user");
String username = user.getUsername();
//记录user登录时间,存入日志
String message = username+" 登录时间:"+new Date();
writer.write(message+"\r\n");
writer.flush();
writer.close();
}
}
5.3 OrderController订单controller
订单模块
@Controller
@RequestMapping("/toOrder")
public class OrderController {
@RequestMapping(path = "/orderInfo.action",method = {
RequestMethod.GET,RequestMethod.POST})
public String query(Integer id){
System.out.println("订单信息");
return "order";
}
}
5.4 CartController购物车controller
购物车模块
@Controller
@RequestMapping("/toCart")
public class OrderController {
@RequestMapping(path = "/cartInfo.action",method = {
RequestMethod.GET,RequestMethod.POST})
public String query(Integer id){
System.out.println("购物车信息");
return "cart";
}
}
5.5 springmvc中配置拦截器
<!--配置用户权限拦截器-->
<mvc:interceptors>
<!--用于测试的拦截器-->
<mvc:interceptor>
<!--拦截路径的配置 /**拦截所有请求 -->
<mvc:mapping path="/**"/>
<bean id="interceptor1" class="com.xgf.interceptor.UserAuthInterceptor"/>
</mvc:interceptor>
<!-- 可以配置多个拦截器,继续用mvc:interceptor-->
</mvc:interceptors>
大佬们,画图不容易啊,给个关注给个赞呗,感谢感谢=
转载:https://blog.csdn.net/qq_40542534/article/details/109123857
查看评论