`

使用拦截器

 
阅读更多
23.4  使用拦截器

和Struts2一样,Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口。

【示例23-9】HandlerInterceptor接口的代码如下:

    package org.springframework.web.servlet; 
    import Javax.servlet.http.HttpServletRequest; 
    import Javax.servlet.http.HttpServletResponse; 
    public interface HandlerInterceptor { 
        // preHandle()方法在业务处理器处理请求之前被调用 
        boolean preHandle(HttpServletRequest request,
    HttpServletResponse response, 
        Object handler) 
            throws Exception; 
        // postHandle()方法在业务处理器处理请求之后被调用 
        void postHandle( 
                HttpServletRequest request, HttpServletResponse
    response, Object 
                handler, ModelAndView modelAndView) 
                throws Exception; 
        // afterCompletion()方法在DispatcherServlet完全处理完请求后被调用 
        void afterCompletion( 
                HttpServletRequest request, HttpServletResponse
    response, Object 
                handler, Exception ex) 
                throws Exception; 
    
    }

下面对代码中的三个方法进行解释。

preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。

postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet向客户端返回请求前被调用,在该方法中对用户请求request进行处理。

afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

下面通过一个例子来说明如何使用Spring MVC框架的拦截器。

【示例23-10】要求编写一个拦截器,拦截所有不在工作时间的请求,把这些请求转发到一个特定的静态页面,而不对它们的请求进行处理。

首先编写TimeInterceptor.Java,代码如下:

    package com.examp.ch23; 
    import Java.util.Calendar; 
    import Javax.servlet.http.HttpServletRequest; 
    import Javax.servlet.http.HttpServletResponse; 
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 
    
    public class TimeInterceptor extends HandlerInterceptorAdapter { 
                                            //继承HandlerInterceptorAdapter类 
    
        private int openingTime;            //openingTime 属性指定上班时间 
        private int closingTime;            //closingTime属性指定下班时间 
        private String outsideOfficeHoursPage; 
                                            //outsideOfficeHoursPage属性指定错误 
                                              提示页面的URL 
        public void setOpeningTime(int openingTime) { 
            this.openingTime = openingTime; 
        } 
        public void setClosingTime(int closingTime) { 
            this.closingTime = closingTime; 
        } 
        public void setOutsideOfficeHoursPage(String outsideOfficeHoursPage) { 
            this.outsideOfficeHoursPage = outsideOfficeHoursPage; 
        } 
        //重写 preHandle()方法,在业务处理器处理请求之前对该请求进行拦截处理 
        public boolean preHandle( 
                HttpServletRequest request, 
                HttpServletResponse response, 
                Object handler) 
        throws Exception { 
            Calendar cal = Calendar.getInstance(); 
            int hour = cal.get(Calendar.HOUR_OF_DAY);       //获取当前时间 
            if (openingTime<=hour && hour<closingTime) {    //判断当前是否处于工作 
                                                              时间段内 
                return true; 
            } else { 
                response.sendRedirect(outsideOfficeHoursPage);  //返回提示页面 
                return false; 
            } 
        } 
    }

可以看出,上面的代码重载了preHandle()方法,该方法在业务处理器处理请求之前被调用。在该方法中,首先获得当前的时间,判断其是否在openingTime和closingTime之间,如果在,返回true,这样才会调用业务控制器去处理该请求;否则直接转向一个静态页面,返回false,这样该请求就不会被处理。

下面是在dispatcherServlet-servlet.xml中对拦截器进行的配置,代码如下:

    <bean id="urlMapping" class="org.springframework.web.servlet.handler.Simple- 
    UrlHandlerMapping"> 
            <property name="mappings"> 
                <props> 
                    <prop key="helloWorld.do">helloWorldAction</prop> 
                    <prop key="login.do">loginController</prop> 
                </props> 
            </property> 
            <property name="interceptors"> 
                                    <!--在interceptors 属性中定义所有的拦截器--> 
                <list> 
                    <ref bean="officeHoursInterceptor"/> 
                                    <!--引用officeHoursInterceptor 拦截器--> 
                </list> 
            </property> 
             
    </bean> 
    <!--定义TimeInterceptor拦截器,id为officeHoursInterceptor --> 
    <bean id="officeHoursInterceptor"
          class="com.examp.ch23.TimeInterceptor"> 
        <!--openingTime 属性指定上班时间--> 
        <property name="openingTime"><value>9</value></property> 
        <!--closingTime属性指定下班时间--> 
        <property name="closingTime"><value>18</value></property> 
         <!--outsideOfficeHoursPage属性指定提示页面的URL--> 
        <property name="outsideOfficeHoursPage"><value>http://localhost:8080/ 
        ch23/outsideOfficeHours.html</value></property> 
    </bean>

可以看出,上面代码用bean标签去定义TimeInterceptor,令其id为officeHoursInterceptor,并给它的3个属性赋值。在urlMapping中通过<property name="interceptors">去指定officeHoursInterceptor为一个拦截器,读者可以在<list>和</list>之间定义多个拦截器。

outsideOfficeHours.html的代码很简单,只是输出一句提示语。

运行程序,在浏览器中随便访问一个页面,如果请求的时间在9点~18点之间,则该请求可以被处理;否则,返回一句提示语,如图23-5所示。

(点击查看大图)图23-5  请求被拦截效果图
说明:在第22章中介绍过控制反转是Spring框架的核心思想,即用一个接口去定义一些操作,在接口的实现类中去重写这些操作,然后在Spring的配置文件中去把该接口的实现类注入到应有框架中,这样就可以通过调用接口去调用接口的实现类。本节讲的拦截器就体现了这种思想,即实现HandlerInterceptorAdapter接口,重写preHandle()方法并在配置文件中实现TimeInterceptor的注入。这样当框架调用HandlerInterceptorAdapter时,就可以调用到TimeInterceptor类的preHandle()方法。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics