5

我试图找出一种方法来避免必须从所有拦截器中排除静态内容,而不必为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(因为不应该真正有理由拦截资源)。

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

谢谢

4

1 回答 1

5

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

一个可以实现您想要的快速代码解决方案将类似于:

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 实现扩展这个抽象类。由于 <mvc:resources> 基本上是注册 ResourceHttpRequestHandler 实例的一种快捷方式,这将确保您的 HandlerInterceptor 实现简单地忽略任何映射为由一个处理的请求。

于 2013-08-23T15:02:55.533 回答