• SpringMVC 处理静态资源


    一、前言

    关于 DispatcherServlet 为什么要配置成 / ,具体的可以参考这篇博客: https://i.cnblogs.com/posts/edit;postId=11869540

    如果把 DispatcherServlet 的 url-pattern 配置成  /* ,那么它会覆盖掉 Jspservlet ,所有的 jsp 请求最交给 DispatchServlet 处理,如果 Controller 中没有配置相关处理方法那么会无法处理.事实上没有必要越俎代庖的处理 .jsp 请求,完全可以交给 Tomcat 容器处理 jsp 请求,因此 DispatchServlet 要配置成  /

    看培训班的视频或者早期的 SpringMVC 资料,他们把 DispatchServlet 配置成 .do 或者 .action 的形式,那是因为早期的 SpringMVC 缺乏对静态资源的管理,如果配置成 / 那么所有对静态资源如 js 的请求也会交给 DIspatchServle t处理,除非配置相应的 Controller 否则也会报错,所有静态资源管理的任务还是应该由 Tomcat 中的 default 来管理,因此早期 DispatchServlet 配置成  *.do  或  *.action 等形式来避免覆盖掉default 的功能.
    这种 url 风格是不符合 REST 的要求的,所以后来 SpringMVC 加入了两个重要的注解,它们结合使用产生的功效是如果 DispatchServlet 发现请求是一个静态资源那么会交给 default servlet 即交给 Tomcat 处理,效果拔群.

    总之最后的结论是:

    1、DispatcherServlet 的 <url-pattern> 配成 /

    2、springMVC 的配置文件里加上下面两个注解   

    <mvc:default-servlet-handler/>
    <mvc:annotation-driven></mvc:annotation-driven>
    

     

    二、为什么加上了上述两个注解静态资源访问就没有问题了呢?打上断点来查看加注解前后的区别.

    1、首先是两个注解都不加,此时 HandlerMappings 中的 DefaultAnnotationHandlerMapping 中存储着 Controller 和 URL 的映射关系,由于我们没有编写 Controller 去处理 js、html 等静态资源.所以此时的状态是动态资源可以访问,静态资源不可访问.( DefaultAnnotationHandlerMapping 用来处理动态资源)

    2、只加上 default-servlet-handler ,发现处理 Controller 的 DefaultAnnotationHandlerMapping 不见了,取而代之的是 SimpleURLHandlerMapping ,该 Handler 中的handlerMap 非常简单只有一个 /** 即无论什么请求都直接去当前 webapp 下去找,这样配置静态资源肯定是可以访问的,因为它的作用和不使用 SpringMVC 中的 DispatcherServlet 直接使用Tomcat 一样.但由于 AnnotationHandler 的缺失,导致 Controller 这种基于注解配置处理请求的方法无法访问,所以这种配置下的状态是静态资源可以访问,动态资源不可以访问.

     

    3、当把两个注解都加上的时候,不仅有处理静态资源的 SimpleUrlHandlerMapping ,还多了一个优先级最高的 RequestMapping ,点开详情信息发现我们配置的 Controller 都在里面.这就是我们要的效果.
    对于每一个非 jsp 请求都会被 DispatchServlet 拦下,然后交给优先级最高的 RequestMapping 处理. RequestMapping 遍历自己的 Mappings ,如果这个请求是一个动态请求,那么一定可以找到对应的 Controller, Controller 处理并返回,如果该请求是一个针对静态资源文件的, RequestMapping 无能为力,他会按照优先级交给后续 HandlerMapping 如没啥用的BeanNameUrlHandlerMapping ,以及放在最后用来兜底的 SimpleUrlHandlerMapping ,当 SimpleUrlHandlerMapping 拿到一个针对静态资源的请求后,会在 /** 目录下找到静态资源并返回.

     

     

    三、总结
    1、如果两个注解都不加,那么会有一个 DefaultAnnotationHandlerMapping ,它里面存储着 Controller 和 URL 的映射关系,用来处理动态资源
    2、如果只加 <mvc:default-servlet-handler/> ,那么会有一个 SimpleURLHandlerMapping ,它里面的 handlerMap 匹配的是 /**,也就是可以去项目路径下访问所有资源,但是由于缺少AnnotationHandler ,所以不能处理动态资源,只能处理静态资源.
    3、如果两个注解都加上,会同时存在一个 SimpleURLHandlerMapping 和一个优先级比它高的 RequestMappingHandlerMapping,它的实际作用类似于 DefaultAnnotationHandlerMapping,用于处理动态资源,它处理完了动态资源之后然后剩下的静态资源再交给 SimpleURLHandlerMapping 去处理

     

     

     

    转载至:https://www.cnblogs.com/AshOfTime/p/10655014.html

  • 相关阅读:
    CSplitterWnd 成员介绍及切分条的定制
    时空数据挖掘 Mining Complex SpatioTemporal Sequence Patterns
    动态布局切分窗口
    不管你现在多穷多蠢,只要抓住一个上升的载体你就能变成富人
    破解了小区宽带的限制
    VC6.0的若干实用小技巧
    恶搞程序发布(更新版本)
    WPF笔记
    做多维数据集需要注意的两个细节
    关于值类型和引用类型的备忘
  • 原文地址:https://www.cnblogs.com/xiaomaomao/p/13606023.html
Copyright © 2020-2023  润新知