Spring MVC中的拦截器
创始人
2024-03-13 17:57:06
0

在之前学习JAVAWEB 的时候,我们学习了过滤器的知识。过滤器的作用是保护请求的服务器资源,在请求资源被执行之前,如果请求地址符合拦截范围,则会先执行过滤器。过滤器的执行时机,是在Servlet之前执行的。但是在使用了SpringMVC后,Servlet只有一个了,也就是DisptcherServlet。那么,如果我们仍然使用过滤器来完成请求的拦截,因为过滤器是在Servlet之前执行的,就会造成,过滤器会拦截DispatcherServlet所有的请求。那么,如果我们有部分请求不想被拦截,怎么办?

拦截器使用


Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
    要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。
    1.通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。
    2.通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。

 

拦截器和过滤器的区别


       1拦截器SpringMVC的,而过滤器是servlet的。
  2拦截器不依赖与servlet容器,由spring容器初始化,过滤器依赖与servlet容器,由servlet容器初始化。
  3拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  4拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  5在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
       6拦截器可以获取IOC容器中的各个bean,而过滤器就不太方便,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

1.定义一个拦截器

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/*在请求到达我们定义的handler之前工作的*/System.out.println("MyInterceptor preHandle");/*返回的是true,代表放行,可以继续到达handler*/return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor postHandle");/*handler 处理单元返回ModelAndView 时候进行 拦截*/}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {/*页面渲染完毕,但是还没有给浏览器响应数据的时候*/System.out.println("MyInterceptor afterCompletion");}
}


2.springmvc.xml中注册拦截器

   


拦截器内容详解


1、preHandle方法

  • 执行时机:  再进入控制单元方法之前执行
  • 如何调用:  按拦截器定义顺序调用
  • 具体作用:  如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去 进行处理,则返回 true。 如果程序员决定不需要再调用其他的组件去处理请求,则返回 false。
  • 参数详解
  1.   HttpServletRequest arg0,拦截的请求的request对象
  2.     HttpServletResponse arg1, 拦截的请求的response对象
  3.     Object arg2       封存了单元方法对象的HandleMethod对象 

   

 /**** @param request  请求对象* @param response 响应对象* @param handler  目标要调用的Handler* @return 返回true放行,返回false拦截* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/*在请求到达我们定义的handler之前工作的*/System.out.println("MyInterceptor preHandle");/*设置请求和响应的乱码 *//* request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");*/// 判断是否登录/*User user =(User) request.getSession().getAttribute("user");if(null == user)response.sendRedirect("index.jsp");return false;*/// 用户权限控制return true;}

2、postHandle方法

  • 执行时机: 在进行数据处理和做出响应之间进行这个方法的调用
  • 如何调用  :在拦截器链内所有拦截器返成功调用
  • 具体作用:  在业务处理器处理完请求后,但是 DispatcherServlet 向客户端返回响应前被调用,
  • 在该方法中对用户请求 request域数据进行处理。
  • 参数详解
  1.         HttpServletRequest arg0, 拦截的请求的request对象
  2.         HttpServletResponse arg1, 拦截的请求的response对象
  3.         Object arg2, 封存了单元方法对象的HandleMethod对象
  4.         ModelAndView arg3 封存了单元方法的返回值资源路径和请求转到的Map数据 
/**** @param request* @param response* @param handler* @param modelAndView  controller响应的结果,视图和数据* @throws Exception*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor postHandle");/*控制数据*//*Map map = modelAndView.getModel();String msg = (String)map.get("msg");String newMsg = msg.replaceAll("脏话", "**");map.put("msg", newMsg);*//*控制视图*//*modelAndView.setViewName("/testDemo1.jsp");*/}


3、afterCompletion方法

执行时机:  在进行页面渲染的时候执行

  • 如何调用:  按拦截器定义逆序调用  
  • 具体作用:  在DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
  • 参数详解
  1.         HttpServletRequest arg0, 拦截的请求的request对象
  2.         HttpServletResponsearg1, 拦截的请求的response对象
  3.         Object arg2, 封存了单元方法对象的HandleMethod对象
  4.         Exception arg3 存储了责任链的异常信息
/*** 无论controller是否出现异常,都会执行的方法*  一般来说都做一些资源释放工作* @param request* @param response* @param handler* @param ex* @throws Exception*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {/*页面渲染完毕,但是还没有给浏览器响应数据的时候*/System.out.println("MyInterceptor afterCompletion");System.out.println(ex);}

多个拦截器执行顺序

多个拦截器同时存在时,执行的顺序由配置顺序决定. 先配置谁, 谁就先执行.多个拦截器可以理解为拦截器栈, 先进后出(后进先出), 如图所示:

执行结果: 

MyInterceptor preHandle
MyInterceptor2 preHandle
login.action
MyInterceptor2 postHandle
MyInterceptor postHandle
success.jsp 
MyInterceptor2 afterCompletion
MyInterceptor afterCompletion
 

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...