欢迎页设置和访问静态资源

处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了。

因为一个网站的显示肯定会依赖各种资源:脚本、图片等,那么问题来了,如何在页面中请求这些静态资源呢?

还记得Spring MVC中的DispatcherServlet吗?它是Spring MVC中的前置控制器,若配置的拦截路径为“/”,那么所有的请求都将被它拦截。对静态资源的访问也属于一个请求,那么也会被它拦截,然后进入它的匹配流程,我们知道它是根据HandlerMapping的配置来匹配的。而对于静态资源来说,默认的Spring MVC是没有注册匹配规则的,此时若你去请求一个静态资源,则会报404错误。但是如果请求的是静态网页,就会访问默认首页面了。因为大多服务器web.xml缺省下的访问首页面就是如下设置的,因此默认设置时会访问webapp目录(根目录)下面的静态页面。

<welcome-file-list>
 <welcome-file>index.html</welcome-file>
 <welcome-file>index.htm</welcome-file>
 <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

改变欢迎页的默认设置

  1. 可以通过如下的方式,指定首页要显示的视图页面(下面访问/WEB-INF/views下面的hello.jsp):
<welcome-file-list>
       <welcome-file>/WEB-INF/views/hello.jsp</welcome-file>
    </welcome-file-list>

    2. 设置拦截路径为*do,此外*.html, *.htm,这个的规则跟 *.do 差不多;

<servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

就没有默认首页面了,所以还得添加默认访问页:

<welcome-file-list>
        <welcome-file>home.do</welcome-file>
    </welcome-file-list>

打开 home.jsp 所对应的 RequestMapping 注入方法处,一般homeController.java,修改拦截 value 值为 home 或 home.do,本来为 "/";

RequestMapping(value = "home.do", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
        
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        String formattedDate = dateFormat.format(date);
        model.addAttribute("serverTime", formattedDate );
         return "home";
    }
      3./*———就是 把 *.do 改为 "/*"。

这种方式,与 "/" 应该差不多,访问 /home 时, 可以访问到页面,但无法解析页面内部的 动态代码;

访问静态资源

1. 激活Tomcat的defaultServlet来处理静态文件:

在web.xml的 DispatcherServlet 前输入下面的内容;

复制代码
<!-- 静态资源 -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.gif</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.png</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>
复制代码

每个后缀独立配置;这样就能正常的访问静态资源了;

不同的servlet 容器或服务器,处理这些静态资源的名称不一样:

Tomcat, Jetty, JBoss, and GlassFish  默认 Servlet的名字 -- "default"
Google App Engine 默认 Servlet的名字 -- "_ah_default"
Resin 默认 Servlet的名字 -- "resin-file"
WebLogic 默认 Servlet的名字  -- "FileServlet"
WebSphere  默认 Servlet的名字 -- "SimpleFileServlet" 

2. 我们可以配置一个处理静态资源的HandlerMapping

    <bean id="resourceHttpRequestHandler" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">  
        <property name="locations" value="classpath:/META-INF/resources/"></property>     
    </bean>  
      
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
        <property name="mappings">  
            <props>  
                <prop key="/resources/**">resourceHttpRequestHandler</prop>  
            </props>  
        </property>  
    </bean>  

其中ResourceHttpRequestHandler就是处理静态资源请求的类,当然如果你愿意,也可以自己尝试写一个。不过现在这样自己写SimpleUrlHandlerMapping比较少了吧,项目中都是采用的注解配置,只不过是将匹配关系放到注解上

       3.  从 spring 3.0.4 提供 <resources /> 或 <mvc:resource />,还可以使用mvc命名空间的resources标签来配置

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

本质上也是把ResourceHttpRequestHandler注册到SimpleUrlHandlerMapping上。

4. Spring MVC还提供了一个配置项:mvc:default-servlet-handler将在 SpringMVC 上下文中定义一个DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求, 就将该请求交由 WEB 应用服务器默认的 Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理
一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定

这个标签对于匹配规则为"/"的DispatcherServlet才生效(因为别的匹配规则一般也不会拦截静态资源)。它会为DefaultServletHttpRequestHandler配置上"/**"的拦截规则和最低的匹配优先级。DefaultServletHttpRequestHandler处理请求时会将其全部转发到容器的DefaultServlet上。因此它在 HandlerMapping必须是优先级最低的。如果你使用<mvc:annotation-driven>或你使用了自定义的 HandlerMapping实例,确保它们的order值比DefaultServletHttpRequestHandler小 (Integer.MAX)。另外需要注意的是,这里寻找容器的DefaultServlet是用名字而不是路径。所以首先要搞清楚容器的DefaultServlet的名字, 当然一般主流容器的名字是无需指定的,比如Tomcat, Jetty, JBoss, and GlassFish等。若非常用容器,则可能需要手动指定:

    <mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>  

这种方式也是依赖于容器的DefaultServlet的,那么我们是否能直接用容器的DefaultServlet来处理静态资源请求,而不是这样先通过Spring MVC来转发呢?(相比性能上会好很多),答案是肯定的。

比如我们将资源文件都放在resouces目录下,那么只需要在web.xml中配置:

    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>/resource/*</url-pattern>  
    </servlet-mapping>  

并将它放在所有Servlet的最前面(为了让它最先匹配),这样的话性能上应该比较好

但是这样还会有个问题,就是无法访问到classpath下的资源文件,看了tomcat的DefaultServlet的配置项,似乎也没有可以指定目录的地方。

所以,综上所述,性能最好的应该是直接利用容器的DefaultServlet,让它最先拦截静态资源请求,这样就避免了后续的转发等操作,提高了 性能,但是无法访问classpath下的资源文件。而通过mvc:resources标签可以简单配置匹配规则和资源文件路径,应该说是最简单快捷的一 种方式,当然这大概也是mvc命名空间设计的初衷。

如果 *.do 这样的拦截规则,配置上面的 servlet 处理资源 default 方式跟 resources配置 , 都是没有效果的,但都能以原文件夹路径正常访问!


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值