• spring Handler 映射


    Spring 的前几个版本,开发者都需要在 web 应用的上下文定义(多个) HandlerMapping bean,用来将 web 请求映射到指定的 handler。可当引入注解控制器时,开发者基本不再需要这样配置。因为 RequestMappingHandlerMapping 会自动寻找所有 @Controller bean 中的 @RequestMapping 注解。另外提醒一下,所有从 AbstractHandlerMapping 继承过来的 HandlerMapping 类,都以通过设置以下属性来自定义其行为:

    • interceptors 拦截器链。 HandlerInterceptors 会在 Section 16.4.1, “使用 HandlerInterceptor 拦截请求” 谈论。
    • defaultHandler 默认 handler。此 handler 不影响其他 handler 的使用。
    • order order 属性 (可查看 org.springframework.core.Ordered 接口), Spring会对可匹配的 handler 进行排序,并应用第一个匹配到 handler。
    • alwaysUseFullPath 当此属性为 true 时,Spring 会使用当前 Servlet 上下文的全路径去寻找合适的 handler。当为 false 时(默认值),Spring 会使用相对路径来寻找合适的 handler。举个例子,当 某个 Servlet 映射 /testing/* 请求时,若 alwaysUseFullPath 属性为 true,会使用 /testing/viewPage.html;反之,使用 /viewPage.html
    • urlDecode 从 Spring 2.5 开始,此属性默认为 true。如果你更需要编码路基路径,可将此属性设置为 true。然而,HttpServletRequest 总会暴露解码后的 Servlet 路径。另外注意的是,当比较编码后的路径时,Servlet 路径是不会再匹配的。

    如下例子,演示了如何配置一个拦截器:

    <beans>
        <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
            <property name="interceptors">
                <bean class="example.MyInterceptor"/>
            </property>
        </bean>
    <beans>

    16.4.1 使用 HandlerInterceptor 拦截请求

    Spring 的 handler 映射机制包含了 handler 拦截器。使用handler 拦截器,可以在某些的请求中应用的特殊的功能,比如说,检查权限。

    handler 映射的拦截器必须实现 HandlerInterceptor 接口(此节接口位于 org.springframework .web.servlet 包中)。这个接口定义了三个方法:preHandle(..)在 handler 执行前调用;postHandle(..) 在handler 执行后调用;afterCompletion(..) 在整一个请求完成后调用。这三个方法基本足够应对各种预处理和后处理的状况。

    preHandle(..) 方法返回一个 boolean 值。你可以使用这个方法来中断或继续处理 handler 执行链。当此方法返回 true 时,hadler 执行链会继续执行;反之,DispatcherServlet 会认为此拦截器已处理完成该请求(和渲染一个视图),之后不再执行余下的拦截器,也不在执行 handler 执行链。

    可以使用 interceptors 属性配置拦截器。所有从 AbstractHandlerMapping 继承过来的 HandlerMapping 类都拥有此属性。演示例子如下:

    <beans>
        <bean id="handlerMapping"
                class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
            <property name="interceptors">
                <list>
                    <ref bean="officeHoursInterceptor"/>
                </list>
            </property>
        </bean>
    
        <bean id="officeHoursInterceptor"
                class="samples.TimeBasedAccessInterceptor">
            <property name="openingTime" value="9"/>
            <property name="closingTime" value="18"/>
        </bean>
    <beans>
    package samples;
    
    public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
    
        private int openingTime;
        private int closingTime;
    
        public void setOpeningTime(int openingTime) {
            this.openingTime = openingTime;
        }
    
        public void setClosingTime(int closingTime) {
            this.closingTime = closingTime;
        }
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                Object handler) throws Exception {
            Calendar cal = Calendar.getInstance();
            int hour = cal.get(HOUR_OF_DAY);
            if (openingTime <= hour && hour < closingTime) {
                return true;
            }
            response.sendRedirect("http://host.com/outsideOfficeHours.html");
            return false;
        }
    }

    通过这样的配置,所有请求 handler 都会被 TimeBasedAccessInterceptor 拦截。如果当前时间是下班时间,用户会重定向到一个静态页面,换句话说就是,你只能在上班时间访问该网站。

    [提示]

    当使用 RequestMappingHandlerMapping 时,真实的 handler 是一个HandlerMethod 实例,该实例指定了会被调用的控制器方法。

    如你所见,Spring 的适配器类 HandlerInterceptorAdapter,使继承 HandlerInterceptor 接口变得更加简单。

    [Tip]

    在上述例子中,所配置的拦截器会应用到所有带注解的请求处理器。如果需要缩窄拦截器的拦截 url 路径范围,可以使用 MVC 命名空间或 MVC Java 配置,或声明 MappedInterceptor 类型的 bean 来缩窄拦截器的拦截范围,详情可参考 Section 16.16.1, “启用 MVC Java 配置或 MVC XML 命名空间”

    注意,HandlerInterceptor 的 postHandle 方法不一定适用于@ResponseBodyResponseEntity方法。在这种情况下,HttpMessageConverter 实例会在 postHandle 方法执行之前就将数据写到 response 并提交 response,所以 postHandle 方法不可能再处理 response(如添加一个 Header)。相反,应用程序可以实现 ResponseBodyAdvice ,将其声明为 @ControllerAdvice bean 或将其直接在 RequestMappingHandlerAdapter 中配置它。


  • 相关阅读:
    安装git工具在ubuntu系统
    Ubuntu 16.04安装JDK并配置环境变量-【小白版】
    【gRPC使用问题4】
    【gRPC使用问题3】生成出来无法识别Google.Api.AnnotationsReflection.Descriptor
    LNMP
    Centos下安装Mysql
    yum方式安装的Apache目录详解和配置说明
    Centos下 yum方式安装LAMP
    CentOS配置网易163 yum源
    Apache主配置文件httpd.conf 详解
  • 原文地址:https://www.cnblogs.com/chenny3/p/10226176.html
Copyright © 2020-2023  润新知