写点什么

SpringMVC 之 Interceptor 拦截器之登录拦截器 (1)

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:4197 字

    阅读完需:约 14 分钟

接口中定义了三个方法:preHandle(requsest,response.handle);postHandle(request,response,handle,modleandview);aftercompletion(request,response,handle,ex);下面说说每个方法的作用和作用空间。


1.preHandle(requsest,response.handle) :在请求处理之前调用这个方法,即请求从前台传递到 controller 之前调用的方法,返回值是 boolean,如果返回的是 true,那么继续进行下面两个方法;如果返回的是 false,请求结束;我的拦截器里面获取了 request 中的 session 数据;来验证用户是否登录;如果 flag 为 true 返回 true;反之返回 false;


2.postHandle(request,response,handle,modleandview):由 preHandle 方法的解释我们知道这个方法包括后面要说到的 afterCompletion 方法都只能是在当前所属的 Interceptor 的 preHandle 方法的返回值为 true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。postHandle 方法被调用的方向跟 preHandle 是相反的,也就是说先声明的 Interceptor 的 postHandle 方法反而会后执行,这和 Struts2 里面的 Interceptor 的执行过程有点类型。Struts2 里面的 Interceptor 的执行过程也是链式的,只是在 Struts2 里面需要手动调用 ActionInvocation 的 invoke 方法来触发对下一个 Interceptor 或者是 Action 的调用,然后每一个 Interceptor 中在 invoke 方法调用之前的内容都是按照声明顺序执行的,而 invoke 方法之后的内容就是反向的。


3.aftercompletion(request,response,handle,ex):该方法也是需要当前对应的 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。


代码说明?


import javax.servlet.http.HttpServletRequest;


import javax.servlet.http.HttpServletResponse;


import org.springframework.web.servlet.HandlerInterceptor;


import org.springframework.web.servlet.ModelAndView;


public class SpringMVCInterceptor implements HandlerInterceptor {


/**


  • preHandle 方法是进行处理器拦截用的,顾名思义,该方法将在 Controller 处理之前进行调用,SpringMVC 中的 Interceptor 拦截器是链式的,可以同时存在

  • 多个 Interceptor,然后 SpringMVC 会根据声明的前后顺序一个接一个的执行,而且所有的 Interceptor 中的 preHandle 方法都会在

  • Controller 方法调用之前调用。SpringMVC 的这种 Interceptor 链式结构也是可以进行中断的,这种中断方式是令 preHandle 的返

  • 回值为 false,当 preHandle 的返回值为 false 的时候整个请求就结束了。


*/


@Override


public boolean preHandle(HttpServletRequest request,


HttpServletResponse response, Object handler) throws Exception {


<span style="white-space:pre"> </span>HttpSession session = request.getSession();


Enumeration<String> e = session.getAttributeNames();


HashMap< String, String> map = new HashMap<String, String>();


while(e.hasMoreElements()){


map.put(e.nextElement(),"");


}


if (map.containsKey("isLogin")) {


if (session.getAttribute("isLogin").equals(true)) {


System.err.println("session 中 username is :"+session.get


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


Attribute("username"));


return true;


}else{


System.err.println("isLogin is false!");


response.sendError(501, "你还没有登录呢!");


return false;


}


}else{


System.err.println("there is not exist isLogin flag!");


response.sendError(502, "这里有点问题,请访问登录页面!");


return false;


}


}/** * 这个方法只会在当前这个 Interceptor 的 preHandle 方法返回值为 true 的时候才会执行。postHandle 是进行处理器拦截用的,它的执行时间是在处理器进行处理之 * 后,也就是在 Controller 的方法调用之后执行,但是它会在 DispatcherServlet 进行视图的渲染之前执行,也就是说在这个方法中你可以对 ModelAndView 进行操 * 作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的 Interceptor 拦截器该方法反而会后调用,这跟 Struts2 里面的拦截器的执行过程有点像, * 只是 Struts2 里面的 intercept 方法中要手动的调用 ActionInvocation 的 invoke 方法,Struts2 中调用 ActionInvocation 的 invoke 方法就是调用下一个 Interceptor * 或者是调用 action,然后要在 Interceptor 之前调用的内容都写在调用 invoke 之前,要在 Interceptor 之后调用的内容都写在调用 invoke 方法之后。 */@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {}/** * 该方法也是需要当前对应的 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。该方法将在整个请求完成之后,也就是 DispatcherServlet 渲染了视图执行, * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。 */@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {// TODO Auto-generated method stub}}


2.实现 WebRequestInterceptor 接口:(这个方法我没有使用;先码,方便后期学习)




WebRequestInterceptor 中也定义了三个方法,我们也是通过这三个方法来实现拦截的。这三个方法都传递了同一个参数 WebRequest ,那么这个 WebRequest 是什么呢?这个 WebRequest 是 Spring 定义的一个接口,它里面的方法定义都基本跟 HttpServletRequest 一样,在 WebRequestInterceptor 中对 WebRequest 进行的所有操作都将同步到 HttpServletRequest 中,然后在当前请求中一直传递。? ?(1 )preHandle(WebRequest request) 方法。该方法将在请求处理之前进行调用,也就是说会在 Controller 方法调用之前被调用。这个方法跟 HandlerInterceptor 中的 preHandle 是不同的,主要区别在于该方法的返回值是 void ,也就是没有返回值,所以我们一般主要用它来进行资源的准备工作,比如我们在使用 Hibernate 的时候可以在这个方法中准备一个 Hibernate 的 Session 对象,然后利用 WebRequest 的 setAttribute(name, value, scope) 把它放到 WebRequest 的属性中。这里可以说说这个 setAttribute 方法的第三个参数 scope ,该参数是一个 Integer 类型的。在 WebRequest 的父层接口 RequestAttributes 中对它定义了三个常量:? ?SCOPE_REQUEST :它的值是 0 ,代表只有在 request 中可以访问。? ?SCOPE_SESSION :它的值是 1 ,如果环境允许的话它代表的是一个局部的隔离的 session,否则就代表普通的 session,并且在该 session 范围内可以访问。? ?SCOPE_GLOBAL_SESSION :它的值是 2 ,如果环境允许的话,它代表的是一个全局共享的 session,否则就代表普通的 session,并且在该 session 范围内可以访问。? ?(2 )postHandle(WebRequest request, ModelMap model) 方法。该方法将在请求处理之后,也就是在 Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型 ModelMap 来改变数据的展示。该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,比如在 preHandle 中准备的数据都可以通过 WebRequest 来传递和访问;ModelMap 就是 Controller 处理之后返回的 Model 对象,我们可以通过改变它的属性来改变返回的 Model 模型。? ?(3 )afterCompletion(WebRequest request, Exception ex) 方法。该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而 WebRequest 参数就可以把我们在 preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象,如果在 Controller 中抛出的异常已经被 Spring 的异常处理器给处理了的话,那么这个异常对象就是是 null 。


import org.springframework.ui.ModelMap;


import org.springframework.web.context.request.WebRequest;


import org.springframework.web.context.request.WebRequestInterceptor;


public class AllInterceptor implements WebRequestInterceptor {


/**


  • 在请求处理之前执行,该方法主要是用于准备资源数据的,然后可以把它们当做请求属性放到 WebRequest 中


*/


@Override


public void preHandle(WebRequest request) throws Exception {


// TODO Auto-generated method stub


System.out.println("AllInterceptor...............................");


request.setAttribute("request", "request", WebRequest.SCOPE_REQUEST);//这个是放到 request 范围内的,所以只能在当前请求中的 request 中获取到


request.setAttribute("session", "session", WebRequest.SCOPE_SESSION);//这个是放到 session 范围内的,如果环境允许的话它只能在局部的隔离的会话中访问,否则就是在普通的当前会话中可以访问


request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION);//如果环境允许的话,它能在全局共享的会话中访问,否则就是在普通的当前会话中访问


}


/**


  • 该方法将在 Controller 执行之后,返回视图之前执行,ModelMap 表示请求 Controller 处理之后返回的 Model 对象,所以可以在

  • 这个方法中修改 ModelMap 的属性,从而达到改变返回的模型的效果。


*/


@Override


public void postHandle(WebRequest request, ModelMap map) throws Exception {


// TODO Auto-generated method stub


for (String key:map.keySet())


System.out.println(key + "-------------------------");;


map.put("name3", "value3");


map.put("name1", "name1");


}


/**


  • 该方法将在整个请求完成之后,也就是说在视图渲染之后进行调用,主要用于进行一些资源的释放


*/


@Override


public void afterCompletion(WebRequest request, Exception exception)


throws Exception {


// TODO Auto-generated method stub


System.out.println(exception + "-=-=--=--=-=-=-=-=-=-=-=-==-=--=-=-=-=");


}

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
SpringMVC之Interceptor拦截器之登录拦截器(1)