SpringMVC中handlerInterceptor的添加

来源:互联网 发布:java伪造ip请求头信息 编辑:程序博客网 时间:2024/06/06 03:59

经过之前的整合,所谓的ssm最简单的版本及其最基础功能已经实现,现在所做的就是添砖加瓦,看到实际的项目中有拦截器interceptor,也想看看其中是做什么用,怎么实现的,话不多说,代码中说明。
先来springmvc.xml的配置文件添加拦截器,

<mvc:interceptors>        <mvc:interceptor>            <mvc:mapping path="/**"/>            <bean class="loginInterceptor.LoginInterceptor"></bean>        </mvc:interceptor>    </mvc:interceptors>

在来看在Java代码中怎么添加这个功能,及说明流程

package loginInterceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import entity.User;//拦截器public class LoginInterceptor implements HandlerInterceptor {    @Autowired    HttpSession session;    //不拦截的页面    private static final String[] IGNORE_URI={"/LoginController/login","/LoginController/register","/LoginController/checkEname"};   //过滤的路径    /**以下是api原文,中文是个人的理解     * Callback after completion of request processing, that is, after rendering the view. Will be called on any outcome of handler execution, thus allows for proper resource cleanup.     * Note: Will only be called if this interceptor's preHandle method has successfully completed and returned true!      * As with the postHandle method, the method will be invoked on each interceptor in the chain in reverse order, so the first interceptor will be the last to be invoked.     * 在完成请求过程,也就是返回视图,可能执行一些处理资源回收     * 备注:只有当preHandle方法执行成功,并且返回true才被调用。     * 和postHandler方法一样,在每个拦截器的链上回调,这个方法才被调用,第一个拦截器会在最后被调用     */    @Override    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)            throws Exception {//        System.out.println("请求通过后完成一些清理工作");    }    /**     * Intercept the execution of a handler. Called after HandlerAdapter actually invoked the handler, but before the DispatcherServlet renders the view. Can expose additional model objects to the view via the given ModelAndView.      * DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can post-process an execution, getting applied in inverse order of the execution chain.     * 中断处理,在拦截器返回视图view后适配器调用处理器,显现额外的模型携带的对象给ModelAndView.     * 执行链上的拦截器处理过程,每一个拦截器的组成部分(必不可少),在处理器的末端,每个拦截器执行的方法.在执行链上回调.     */    @Override    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)            throws Exception {//        System.out.println("preHandler()执行返回true结果后,对ModelAndView进行处理");    }    /**     * Intercept the execution of a handler. Called after HandlerMapping determined an appropriate handler object, but before HandlerAdapter invokes the handler.     * 拦截器的处理器,适配器引用处理器之前,映射合适的处理对象后调用.     */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {        System.out.println("进入第一个拦截方法 preHandle(),第一个执行");        boolean flag=false;   //用于存储判断登录的结果,让路径是否通过//        //对请求路径进行判断        String servletPath=request.getServletPath();         System.out.println(servletPath);        //判断请求是否需要拦截        for(String s:IGNORE_URI){            if(servletPath.equals(s)){                flag=true;    //如果是许可范围内的访问路径                break;            }        }        //拦截请求,当前是访问路径在许可范围内,以下所做的就是对非允许范围内的路径(没登录的用户)做拦截        if(flag){   //如果是需要拦截的页面,User==null,用户信息为空                //是不用拦截的页面                System.out.println("放行请求-->controller");        }else{            //不允许的访问路径,需要判断是否有用户信息,没有的话,让其重新登录,就跳转登录界面            //所以需要用户在登录或者注册后就把用户信息放入session中,后面使用邮件发送验证信息,注册的页面就不用拦截.            User u=(User) session.getAttribute("User");            //如果用户不为空,表示已经有登录的用户信息,放行            if(u==null){                System.out.println("没有对象信息,请重新登录");                request.getRequestDispatcher("login.jsp").forward(request, response);                flag=false;            }        }        return flag;    }}

以下说明工作流程,首先用户发送请求,发送请求在到controller层之前来到拦截器部分,拦截器会获取访问路径 String servletPath=request.getServletPath(); 拿到路径,判断是否在非过滤范围内,首先在用户注册时,数据库不可能有用户信息,这个时候过滤,后面工作无法进行,在登录时,session中也没有存储用户信息,过滤,工作也无法进行,所以类似这些不放在过滤的路径中, private static final String[] IGNORE_URI={“/LoginController/login”,”/LoginController/register”,”/LoginController/checkEname”}; 这些就是不用过滤的,功能实现以后,查找一些文档发现有个好的建议是放在ignore.properties文件中,用读取文件的方式比这种字符数组的好,以后看再做优化。
说了半天的过滤路径,现在说下拿到路径之后,也就是需要过滤的路径进行什么操作,也就是用户未登录,不让他访问其他的路径和资源。当时需要过滤的路径,而且用户信息为空null,则让用户返回登录页面,不让进行其他的操作。
剩下的也没其他的代码实现,或者说目前未发现吧。
实现interceptor,需要重写里面三个方法,这个是版本4以后的,之前看的springmvc3中有其他的方法!spring3

spring4
这个项目用的是4,我也只看了下spring4的里面的三个方法,功能已经实现,后面有需要,在做其他的研究。个人看来,主要是这三个方法,最先来到preHandle方法,里面做一些过滤的事情,上面的类中方法文档注释已经说明,当过滤成功时preHandle返回true,再去访问postHandle(),如果返回ModelAndView,对这个对象进行处理,或者处理其中携带的数据(以后项目用返回ModelAndView在研究作用),最后访问afterCompletion()处理一些资源的处理,或者一些清理工作,也可以做写入日志的作用。