zoukankan      html  css  js  c++  java
  • SpringMVC,3种不同的URL路由配置方法(这根本不是一个小问题)

    SpringMVC中配置URL拦截,非常简单。网上找个示例,就能通过。但是,在我做了好几个Web项目,又参与了别人主导的Web项目时,发现URL配置也非常有学问。

    1. 先说说一种比较常见的:

       
    <servlet>
        <servlet-name>theDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring/spring-mvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>theDispatcher</servlet-name>
        <url-pattern>*.html</url-pattern>
      </servlet-mapping>
       让SpringMVC指拦截 动态请求,js、css、img等静态资源不经过Spring,直接让Web容器处理。

       如果配置了拦截器,也只会拦截.html动态请求。

       静态资源不走Spring,也不走拦截器,性能当然是比较好的。

       如果使用了Nginx,配置静态资源拦截,让Nginx处理静态资源的访问。因为Nginx在处理静态资源方面,比Tomcat等Web容器要强。

       缺点:这种拦截动态请求的方法,比较死板。

    2.  我自己经常有一种需求,http://FansUnion.cn/news 这种不指定.html后缀的其实也是 动态请求,所以我在配置url-pattern喜欢用“/”,即拦截所有的请求。URL是可以灵活配置了,问题又来了,静态资源不再由Tomcat处理,所以必须在SpringMVC中再次配置,
    <mvc:resources mapping="/static/**" location="/static/" />
      让SpringMVC把static静态资源也处理了。显然,让SpringMVC处理静态资源的性能没有Tomcat直接处理比较高。
    理论上,请求中转的次数越多, 性能越差。
      
      本以为万事大吉,虽然静态资源的性能较低,至少程序可以正常运行了,“反正是混过去了”。

       进一步的需求,如果在Spring中配置了登录等拦截器,这个时候也会把 静态资源给拦截进来。
    <mvc:resources mapping="/static/**" location="/static/" /> 这种URL映射,也无法逃脱拦截器的魔爪。

      我是怎么发现这个问题的呢?
    public class BaseLoginInterceptor extends HandlerInterceptorAdapter {
    public boolean preHandle(HttpServletRequest request,
    HttpServletResponse response, Object handler) throws Exception {
    LoginUtil.setCurrentUser(null);
    initCurrentUser(request, response);
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    } 

    公司的项目,Boss的登录拦截器配置如上,“
    HandlerMethod handlerMethod = (HandlerMethod) handler;”。但是我在自己的项目中,发现这行代码是有问题的。如果静态资源被拦截到,会报错:
    java.lang.ClassCastException: org.springframework.web.servlet.resource.ResourceHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod
    通过异常可以发现, Object handler是ResourceHttpRequestHandler ,而不是HandlerMethod。
    因为 
    mvc:resources把静态资源请求交给了ResourceHttpRequestHandler 处理,因此强制转换是有问题的。

    公司项目中Boss的配置之所以没有出现问题,是因为他配置的是只拦截“.html” 动态请求,所以强制转换总是成立的。
    ---------------------------------------------
    我们分析了上述两种情况, 发现“根本矛盾”“根本需求”是啥?
    1.动态请求的URL应该非常灵活,/news /news.html都应该算作动态请求。
    2.SpringMVC的url-pattern可以配置 / , *.html,或者正则表达式,但是我不太喜欢用正则表达式。
    3.如果可能,SpringMVC最好不要拦截静态资源,让Tomcat容器直接处理更好。
        <mvc:resources mapping="/static/**" location="/static/" />
       这是为了性能考虑。
    4.如果线上服务器配置了Nginx,我可以选择让Nginx拦截静态请求,因为比Tomcat处理性能更高。
       本地是否配置Nginx,都不需要改动任何代码。

    -------------------------------------------------
    上面说的 第一种方法的缺陷是,url配置不够灵活。
    第二种方法的缺陷是,SpringMVC要拦截静态资源,而且登录拦截器 也会拦截 静态资源,不但性能差,程序还得再次修改,判断HandlerMethod的实际类型。

    3.终极解决方案: 
      以我习惯用的第2种方法为基础,进一步改进:
      去掉
    <mvc:resources mapping="/static/**" location="/static/" />,不做静态资源请求的映射。
      
    在web.xml里增加如下配置:
    <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
    </servlet-mapping>

    上述配置,
    激活Tomcat的defaultServlet来处理静态文件。

    千万要注意,上述配置,要在 SpringMVC的拦截器DispatchServlet之前。 
      
    参考了:http://blog.chinaunix.net/uid-20586655-id-3000946.html 第七部分
    网友提问:http://www.iteye.com/problems/66915http://www.iteye.com/problems/69983

    这样 SpringMVC不再响应静态资源,登录拦截器也没有问题了。

    ------------------------------------------------------------------------
    详细讨论了上诉3种情况,我的结论是:URL配置根本不是一个简单的问题。

    搞IT这门高科技技术的Coder,真心需要研究啊。今天搞点小功能,遇到各种问题,探究了好久,才理清了脉络,单单是解决问题,而不能找到根本原因,在遇到下一个问题的时候,会再次束手无策。 

    原文首发:
    http://fansunion.cn/article/detail/61.html 
  • 相关阅读:
    关于celery踩坑
    关于git的分批提交pull requests流程
    SymGAN—Exploiting Images for Video Recognition: Heterogeneous Feature Augmentation via Symmetric Adversarial Learning学习笔记
    AFN—Larger Norm More Transferable: An Adaptive Feature Norm Approach for Unsupervised Domain Adaptation学习笔记
    Learning to Transfer Examples for Partial Domain Adaptation学习笔记
    Partial Adversarial Domain Adaptation学习笔记
    Partial Transfer Learning with Selective Adversarial Networks学习笔记
    Importance Weighted Adversarial Nets for Partial Domain Adaptation学习笔记
    Exploiting Images for Video Recognition with Hierarchical Generative Adversarial Networks学习笔记
    improved open set domain adaptation with backpropagation 学习笔记
  • 原文地址:https://www.cnblogs.com/qitian1/p/6463148.html
Copyright © 2011-2022 走看看