Spring MVC - 从所有拦截器中排除资产

时间:2013-08-23 14:08:43

标签: spring spring-mvc

我试图想办法避免从所有拦截器中排除静态内容,而不必为每个应该忽略这些拦截器的拦截器指定exclude-mapping标记。我的context.xml的一部分如下:

<mvc:resources mapping="/assets/**" location="/assets/"/>

<mvc:interceptors>

    <bean class="com.myapp.security.interceptor.SecurityInterceptor" />

    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <mvc:exclude-mapping path="/assets/**" />
        <bean class="com.myapp.interceptor.MessageInterceptor" />
    </mvc:interceptor>

</mvc:interceptors>

如您所见,我已将/assets/指定为从MessageInterceptor中排除。但是,我也希望SecurityInterceptor也排除资源。在DRY之后,为每个拦截器指定exclude-mapping似乎是不合理的(因为绝不应该有理由拦截资源)。

我四处搜寻,找不到任何解决方案。任何帮助表示赞赏!

由于

1 个答案:

答案 0 :(得分:4)

我很难想出任何方法来实现你想要的配置。也许其他人可以提供解决方案。

快速代码解决方案可以达到您想要的效果:

public abstract class ResourceExcludingHandlerInterceptor implements HandlerInterceptor
{

     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
     {
          if (!isResourceHandler(handler))
          {
             doAfterCompletion(request, response, handler, ex);
          }
     }

     public abstract void doAfterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;

     public abstract void doPostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;

     public abstract boolean doPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

     /**
     * <p>
         * Determine if the request is about to be handled by a mapping configured
     * by <mvc:resources>
     * </p>
     * 
     * @param handler
     *            - the handler to inspect
     * @return - true if this is a <mvc:resources> mapped request, false
     *         otherwise
     */
     private boolean isResourceHandler(Object handler)
     {
         return handler instanceof ResourceHttpRequestHandler;
     }

     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
     {
         if (!isResourceHandler(handler))
         {
             doPostHandle(request, response, handler, modelAndView);
         }
     }

     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
     {
         return isResourceHandler(handler) ? true : doPreHandle(request, response, handler);
     }
 }

然后,您可以让HandlerInterceptor实现扩展此抽象类。如&lt; mvc:resources&gt;基本上是注册ResourceHttpRequestHandler实例的简便方法,这将确保您的HandlerInterceptor实现只是忽略映射为由一个处理的任何请求。