【二月】spring-mvc学习之静态资源访问(servlet匹配规则学习)

自满是成功的杀手,唯有持续的奋斗才是成长的源泉
--苏格拉底

最近在学习spring-mvc,在成功搭建spring-mvc的环境后,使用html写了一个简单的登陆页面,但是在启动服务后,访问相应的页面,报404,找不到对应的资源。百思不得其解,于是乎跟了一下源码,尝试一下自己解决。

我使用的版本为:

  • tomcat : 8.5.9
  • spring-webmvc : 4.2.3.RELEASE
  • jstl : 1.2

web.xml中DispatcherServlet的配置如下:

    
        dispatcher
        org.springframework.web.servlet.DispatcherServlet
        1
        
            contextConfigLocation
            classpath:spring/spring-mvc-config.xml
        
    
    
        dispatcher
        /
    

跟源码后发现,在请求对应的html页面的时候,请求被DispatcherServlet处理了,在由其doDispatch处理的时候,无法获取到对应的handler。于是乎自作聪明,想着对对应的html页面写一个Controller不就好了吗?最后发现是不行的,暂时发现对应Controller的页面需要是jsp(这个可能是自己试用jstl解析视图的原因,具体细节还要学)。

可是之前自己在学习servlet的时候,是可以访问静态的html页面的。为什么在使用spring-mvc的框架后会提示无法访问呢?问题就出在DispatcherServlet的路径映射上了。

servlet的路径匹配规则

当键入一个url后,servlet容器是如何进行路径的匹配的呢?具体的匹配规则是什么呢?匹配的顺序是怎样的?

首先,serlvet容器会用请求的url减去当前应用的上下文路径,然后以剩余的字符串进行匹配,假设现在我们请求的url为http://localhost:8080/servlet/index/index.html,他的应用上下文为servlet,容器就会将http://localhost:8080/servlet去掉,使用/index/index.html进行匹配,以选择对应处理请求的serlvet。

servlet 的匹配规则有四种,按匹配顺序排列。

  1. 精确匹配。精确匹配的就是请求的路径与servlet定义的url-pattern完全匹配。

  2. 路径匹配。假如一个资源路径下的所有资源页面对应的请求都需要有一个serlvet进行处理,这可以使用路径匹配规则。路径匹配规则以/开口,并以/*结尾



    servlet
    /index/*

  1. 扩展名匹配。匹配指定扩展名字的文件,路径匹配规则以*.开头


    servlet
    *.html

  1. 默认匹配。默认路径匹配规则的路径就一种:/

⚠️注意:在一个请求经由servlet容器处理的时候,servlet容器按照顺序进行匹配,当匹配中的时候,就将请求交给对应的servlet进行处理,单一匹配。

问题再次分析

很显然,我将DispatcherServlet的匹配路径定义为了默认匹配,然后没有定义其他的servlet,导致所有的请求都有DispatcherServlet进行处理了。所有,如果定义一个可以处理静态资源的serlvet就可以了,由此出发,回想最初使用servlet的时候,为什么可以处理静态资源的访问呢?抱着疑问上网搜索了一下,发现原来在tomcat的conf目录下由一个web.xml文件,打开这个web.xml文件,其中定义了DefaultServlet。我们看一下这个文件:

DefaultServlet.png

其对应定义的匹配路径为:

DefaultServlet路径映射规则

在我后续将DispatcherServlet的路径映射定义为默认后,我定义的覆盖了tomcat的默认的servlet,这就是问题原因了。找到问题原因了,怎么解决呢?

解决办法

解决办法一:

为tomcat的DefaultServlet定义一个优先级更高的匹配。扩展名匹配或者是路径匹配。



 default
 *.html
 *.css
 *.js




 default
 /resource/*

解决办法二:

让spring-webmvc来为我们解决静态资源访问的问题。spring中定义了一个DefaultServletHttpRequestHandler来处理静态资源。我们可以看一下官方对它的介绍:

【二月】spring-mvc学习之静态资源访问(servlet匹配规则学习)_第1张图片
DefaultServletHttpRequestHandler.png

大概的意思就是,这个DefaultServletHttpRequestHandler是spring提供用来处理静态资源的。可以在spring的配置文件中对它进行配置就好了。






自此,静态资源的访问解决了,但是这其实解决了配置问题,其中具体的细节自己还是不了解,还是要深入进行学习。学无止境啊!

你可能感兴趣的:(【二月】spring-mvc学习之静态资源访问(servlet匹配规则学习))