springmvc拦截器

来源:互联网 发布:香港翡翠台直播软件 编辑:程序博客网 时间:2024/06/08 18:36

1、 拦截器
1.1拦截器定义
定义拦截器,实现HandlerInterceptor接口,接口中提供三个方法。

public class HandlerInterceptor implements org.springframework.web.servlet.HandlerInterceptor{    //执行Handler完成执行此方法    //应用场景:统一异常、日志处理    @Override    public void afterCompletion(HttpServletRequest request,            HttpServletResponse response, Object handler, Exception ex)            throws Exception {    }    //进入Handler方法之后,返回modelAndView之前执行    //应用场景从modelAndView出发:将公用的模型数据在这里传到视图(比如菜单导航),也可以在这里统一指定视图    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response,            Object handler, ModelAndView modelAndView) throws Exception {    }    //进入Handler方法之前执行    //用于身份认证,身份授权,如果认证不通过,表示当前用户没有登录,需要此方法拦截不再向下执行    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,            Object handler) throws Exception {        //return false 拦截,不向下执行        return false;    }}

2、 拦截器配置
2.1针对HandlerMapping进行拦截设置。
如果在某个HandlerMapping中配置拦截,经过该HandlerMapping映射成功的handler最终才使用该拦截器。

<bean class="org.springframework.web.servlet.handler.BeanNamerUrlHandlerMapping">        <property name="interceptors">            <list>                <ref bean = "handlerInterceptor1"/>                <ref bean = "handlerInterceptor2"/>            </list>        </property>    </bean>    <bean id="handlerInterceptor1" class="springmvc.interceptor.HandlerInterceptor1"></bean>    <bean id="handlerInterceptor2" class="springmvc.interceptor.HandlerInterceptor2"></bean>
一般不推荐使用

2.2类似全局的拦截器
springMVC配置类似全局的拦截器,springMVC框架将配置类似全局的拦截器注入到每个HandlerMapping中。

<!-- 拦截器 -->    <mvc:interceptors>        <!-- 多个拦截器,顺序执行 -->        <mvc:interceptor>            <!-- path="/**"表示所有URL包括子URL路径 -->            <mvc:mapping path="/**"/>            <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1"></bean>        </mvc:interceptor>        <mvc:interceptor>            <mvc:mapping path="/**"/>            <bean class="cn.itcast.ssm. interceptor.HandlerInterceptor2"></bean>        </mvc:interceptor>    </mvc:interceptors>

3、 拦截器测试
3.1测试需求
测试多个拦截器各个方法执行时机。

3.2编写两个拦截器

HandlerInterceptor1.java
HandlerInterceptor2.java

3.3两个拦截器都放行
控制台输出:
HandlerInterceptor1…preHandler
HandlerInterceptor2…preHandler

HandlerInterceptor2…postHandler
HandlerInterceptor1…postHandler

HandlerInterceptor2…afterCompletion
HandlerInterceptor1…afterCompletion

总结:
preHandler方法按顺序执行
postHandler和afterCompletion按拦截器配置的逆向顺序执行

3.4拦截器1放行,拦截器2不放行

HandlerInterceptor1…preHandler
HandlerInterceptor2…preHandler
HandlerInterceptor1…afterCompletion
总结:
拦截器1放行,拦截器2 preHandler才会执行。
拦截器2 preHandler不放行,拦截器2 的postHandler和afterCompletion方法不会执行。
只要有一个拦截器不放行,postHandler不会执行。

3.5拦截器1不放行,拦截器2不放行
HandlerInterceptor1…preHandler
总结:
拦截器1 preHandler不放行,postHandler和afterCompletion方法不会执行。
拦截器2也不执行。

小结
根据测试结果,对拦截器进行应用。
比如:统一日志处理拦截器,需要改拦截器preHandler一定要放行,且将它放在拦截器连接中第一个位置。

比如:登录认证拦截器,放在拦截器连接中第一个位置。权限校验拦截器,放在登录认证拦截器之后。(因为登录通过后才校验)

4、 拦截器的应用(实现登录认证)
4.1需求
1.用户请求URL
2.拦截器进行拦截校验
如果请求URL是公开地址,让放行
如果用户session不存在跳转到登录页面
如果用户session存在放行,继续操作。
4.2登录controller方法

//登录    @RequestMapping("/login")    public String login(String username,String password)throws Exception{        //调用service进行用户身份验证        //...        //在session中保存用户信息        session.setAttribute("username",username);        //重定向到商品列表页面        return "redirect:/items/queryItems.action";    }    //退出    @RequestMapping("/logout")    public String logout(HttpSession session)throws Exception{        //清除session        session.invalidate();        //重定向到商品列表页面        return "redirect:/items/queryItems.action";    }

4.3登录认证拦截实现

public class LoginInterceptor implements org.springframework.web.servlet.HandlerInterceptor{    //执行Handler完成执行此方法    //应用场景:统一异常、日志处理    @Override    public void afterCompletion(HttpServletRequest request,            HttpServletResponse response, Object handler, Exception ex)            throws Exception {        System.out.println("HandlerInterceptor1..afterCompletion");    }    //进入Handler方法之后,返回modelAndView之前执行    //应用场景从modelAndView出发:将公用的模型数据在这里传到视图(比如菜单导航),也可以在这里统一指定视图    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response,            Object handler, ModelAndView modelAndView) throws Exception {        System.out.println("HandlerInterceptor1..postHandle");    }    //进入Handler方法之前执行    //用于身份认证,身份授权,如果认证不通过,表示当前用户没有登录,需要此方法拦截不再向下执行    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,            Object handler) throws Exception {        //获得请求的URL        String url = request.getRequestURL();        //判断URL是否是公开地址(实际使用时公开地址配置在配置文件中)        //这里公开地址是登录提交的地址         if(url.indexOf("login.action")>0){            //如果进行登录提交,放行            return true;        }        //判断session        HttpSession session = request.getSession();        String username =(String) session.getAttribute("username");        if(username != null){            return true;        }        //执行这里表示用户身份需要认证,跳转登录页面        request.getRequestDispatcher("WEB-INF/login.jsp").forward(request,response);        //return false 拦截,不向下执行        return true;    }}

4.3配置拦截器

<!-- 登录 验证拦截器-->        <mvc:interceptor>            <mvc:mapping path="/**"/>            <bean class="cn.itcast.ssm.interceptor.LoginInterceptor"></bean>        </mvc:interceptor>
原创粉丝点击