可单例开发、典型的教科书式的mvc构架----springmvc----day02(六)

10.拦截器
                10.1定义拦截器,实现HandlerInterceptor接口,接口中提供三个方法。
                    public class HandlerInterceptor1 implements HandlerInterceptor {

                        // 执行Handler完成执行此方法
                        // 应用场景:统一的异常处理,统一日志处理
                        @Override
                        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception exception) throws Exception {
                            System.out.println("HandlerInterceptor1.......afterComletion");
                        }

                        // 进入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 {
                            // return false表示拦截,不再向下执行
                            // return trueb表示方向
                            System.out.println("HandlerInterceptor1.......preHandle");

                            return true;
                        }

                    }

                10.2拦截器配置
                    10.2.1针对HandlerMapping配置
                    springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该HandlerMapping映射成功的handler最终使用该拦截器。
                        <bean
                            class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
                            <property name="interceptors">
                                <list>
                                    <ref bean="handlerInterceptor1"/>
                                    <ref bean="handlerInterceptor2"/>
                                </list>
                            </property>
                        </bean>
                            <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
                            <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

                        一般不推荐使用
                    10.2.2类似全局的拦截器
                        springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。
                            <!-- 拦截器 -->
                            <mvc:interceptors>
                                <!-- 多个拦截器,顺序执行 -->
                                <!-- 登录认证拦截器 -->
                                <mvc:interceptor>
                                    <mvc:mapping path="/**" />
                                    <bean class="com.changemax.ssm.interceptor.LoginInterceptor"></bean>
                                </mvc:interceptor>
                                <mvc:interceptor>
                                    <!-- /**表示所有url路径包括子路径 -->
                                    <mvc:mapping path="/**" />
                                    <bean class="com.changemax.ssm.interceptor.HandlerInterceptor1"></bean>
                                </mvc:interceptor>
                                <mvc:interceptor>
                                    <mvc:mapping path="/**" />
                                    <bean class="com.changemax.ssm.interceptor.HandlerInterceptor2"></bean>
                                </mvc:interceptor>
                            </mvc:interceptors>

                10.3拦截测试
                    10.3.1测试需求
                        测试多个拦截器各个方法执行时机。

                    10.3.2编写两个拦截

                    10.3.3两个拦截器都放行
                        总结:
                            preHandler方法按顺序执行,
                            postHandler和afterCompletion按拦截器配置的逆向顺序执行。

                    10.3.4拦截器1放行,拦截器2不放行
                        总结:
                            拦截器1放行,拦截器2preHandler才会执行。
                            拦截器2preHandler不放行,拦截器2postHandle和afterCompletion不会执行。
                            只要有一个拦截器不放行,postHandle不会执行

                    10.3.5小结
                        根据测试结果,对拦截器应用。

                        比如:统一日志处理拦截器,需要该 拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。

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

                10.4    拦截器应用(实现登陆认证)
                    10.4.1需求:
                        1.用户请求url
                        2.拦截器进行拦截校验
                            如果请求的url是公开地址(无需登录即可访问的url),让放行
                            如果用户session不存在跳转的登录页面
                            如果用户session存在放行,继续操作。

                    10.4.2登录controller方法
                        @Controller
                        public class LoginController{
                            // 登入
                            @RequestMapping("/login")
                            public String login(HttpSession session, 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 {
                                // 调用service进行用户身份验证
                                // ..

                                // 在session中保存用户身份信息
                                session.invalidate();

                                return "redirect:/items/queryItems.action";

                            }
                        }

                    10.4.3登陆认证拦截实现
                        10.4.3.1代码实现
                            public class LoginInterceptor implements HandlerInterceptor {

                                // 执行Handler完成执行此方法
                                // 应用场景:统一的异常处理,统一日志处理
                                @Override
                                public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                        Exception exception) throws Exception {
                                    System.out.println("HandlerInterceptor1.......afterComletion");
                                }

                                // 进入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().toString();

                                    // 判断url是否为公开地址(实际使用时公开地址配置配置文件中)
                                    if (url.indexOf("login.action") >= 0) {
                                        // 如果进行登入提交,就放行
                                        return true;
                                    }

                                    // 判断session
                                    HttpSession session = request.getSession();
                                    // 从session取出用户的身份信息
                                    String username = (String) session.getAttribute("username");

                                    if (username != null) {
                                        return true;
                                    }

                                    //表示用户身份需要认证
                                    request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
                                    
                                    // return false表示拦截,不再向下执行
                                    // return trueb表示方向
                                    System.out.println("HandlerInterceptor1.......preHandle");

                                    return false;
                                }

                            }


                    10.4.3.2拦截器配置
                        <!-- 拦截器 -->
                        <mvc:interceptors>
                            <!-- 多个拦截器,顺序执行 -->
                            <!-- 登录认证拦截器 -->
                            <mvc:interceptor>
                                <!-- /**表示所有url路径包括子路径 -->
                                <mvc:mapping path="/**" />
                                <bean class="com.changemax.mas.interceptor.AdminInterceptor"></bean>
                            </mvc:interceptor>

                        </mvc:interceptors>


 

posted @ 2018-12-25 16:21  CHANGEMAX  阅读(104)  评论(0编辑  收藏  举报