• 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来处理静态文件。
  • 相关阅读:
    Mac OS中使用VScode配置C语言开发环境
    图形数据库(GraphDB)
    将博客搬至CSDN
    Nodejs课堂笔记-第四课 Dynamodb为何物
    Nodejs课堂笔记-第三课 构建一个nodejs的Docker镜像
    Nodejs课堂笔记-第二课 package.json的作用
    MyBatis 3(中文版) 第四章 使用注解配置SQL映射器
    idea hibernate jpa 生成实体类
    Maven常用配置
    spring发送邮件
  • 原文地址:https://www.cnblogs.com/hubing/p/6179670.html
Copyright © 2020-2023  润新知