久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

你真的了解DispatcherServlet的url

 Baruch 2017-09-10

前言

對于springmvc中前端控制器url-pattern配置, 看了很多博客, 發(fā)現(xiàn)好多人理解都是錯(cuò)誤, 并不清楚會攔截什么路徑的請求, 有點(diǎn)小的細(xì)節(jié)并不被大家所關(guān)注.
  • 1
  • 2

DispatcherServlet常見的配置

   <servlet>
       <servlet-name>springmvc</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!-- contextConfigLocation配置springmvc加載的配置文件(配置處理器映射器,適配器等等)
       如果不配置,默認(rèn)加載的是/WEB-INF/[DispatcherServlet 的Servlet 名字]-servlet.xml(springmvc-servlet.xml) -->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:spring/springmvc.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

常見的url-pattern配置有以下三種:

第一種:
'*.xxx', 以指定后綴結(jié)尾的請求都交由DispatcherServlet處理
第二種:
'/' 將會覆蓋容器的default servlet, 凡是在web.xml文件中找不到匹配的URL,,它們的訪問請求都將交給該Servlet處理(靜態(tài)資源也將會攔截). 所以web.xml沒有配置其他特殊路徑的servlet, 基本上所有的請求都交由DispatcherServlet處理.
關(guān)于什么是default servlet, 可以參考我之前的博文.
第三種:
'/*' 錯(cuò)誤的配置,會攔截*.jsp, *.jspx的請求, 使用這種配置最終要轉(zhuǎn)發(fā)到一個(gè)JSP頁面,仍然會由DispatcherServlet, 解析jsp地址, 不能根據(jù)jsp頁面找到handler, 會報(bào)錯(cuò)

對于第一種擴(kuò)展匹配, 是最簡單的. 也是使用最簡單的了.但是現(xiàn)在如此流行restful風(fēng)格的URL, 這種帶小尾巴的URL, 還是有點(diǎn)low的.
第二種配置使用/, 通過該配置是可以實(shí)現(xiàn)rustful風(fēng)格的URL的.

url-pattern配置為 ‘/*’, 為什么是錯(cuò)誤的?

為了驗(yàn)證這種配置, 我做了一個(gè)簡單的測試
在webapp/WEB-INF/jsp下新建test.jsp, controller中只做轉(zhuǎn)發(fā).

@Controller
@RequestMapping("")
public class Test {
    @RequestMapping("/test")
    public String test() {
        return "test";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

測試請求路徑: /test
結(jié)果: 執(zhí)行該請求后404
console打印如下日志:

DispatcherServlet with name ‘taotao-sso’ processing GET request for [/test]
RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /test
RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public java.lang.String com.taotao.sso.controller.Test.test()]
DispatcherServlet]-[DEBUG] Rendering view [org.springframework.web.servlet.view.InternalResourceView: name ‘test’; URL [/WEB-INF/jsp/test.jsp]] in DispatcherServlet with name ‘taotao-sso’
InternalResourceView]-[DEBUG] Forwarding to resource [/WEB-INF/jsp/test.jsp] in InternalResourceView ‘test’
DispatcherServlet]-[DEBUG] DispatcherServlet with name ‘taotao-sso’ processing GET request for [/WEB-INF/jsp/test.jsp]
RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /WEB-INF/jsp/test.jsp
RequestMappingHandlerMapping]-[DEBUG] Did not find handler method for [/WEB-INF/jsp/test.jsp]
PageNotFound]-[WARN] No mapping found for HTTP request with URI [/WEB-INF/jsp/test.jsp] in DispatcherServlet with name ‘taotao-sso’
DispatcherServlet]-[DEBUG] Successfully completed request

從日志可以清晰的看出, springmvc可以找到請求/test的handler, 之后springmvc轉(zhuǎn)發(fā)請求’/WEB-INF/jsp/test.jsp’, 同樣被DispatcherServlet處理, 之后就發(fā)出了/WEB-INF/jsp/test.jsp這樣的轉(zhuǎn)發(fā)請求, 自然會找不到handler, No mapping. 所以這樣的請求會一直為404.

這里DispatcherServlet為什么會繼續(xù)攔截/WEB-INF/jsp/test.jsp?

這里DispatcherServlet配置為:
按照servlet的匹配規(guī)則,,則路徑匹配(/*)會優(yōu)先于擴(kuò)展匹配(*.jsp, *.jspx),導(dǎo)致對jsp的請求會被DispatcherServlet攔截掉。

*.jsp, *.jspx所對應(yīng)的servlet為org.apache.jasper.servlet.JspServlet, 位于tomcat_home/conf/web.xml中, 下文會講到.
對于servlet的匹配規(guī)則和順序不清楚的同學(xué), 可以參看這篇博文

將url-pattern配置為 ‘/’ 看一下控制臺的日志, 對比一下

請求路徑為: /test
結(jié)果: 正確找到view, 并進(jìn)行渲染.

DispatcherServlet]-[DEBUG] DispatcherServlet with name ‘springmvc’ processing GET request for [/test]
RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /test
RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public java.lang.String com.taotao.sso.controller.Test.test()]
DefaultListableBeanFactory]-[DEBUG] Invoking afterPropertiesSet() on bean with name ‘test’
DispatcherServlet]-[DEBUG] Rendering view [org.springframework.web.servlet.view.InternalResourceView: name ‘test’; URL [/WEB-INF/jsp/test.jsp]] in DispatcherServlet with name ‘springmvc’
InternalResourceView]-[DEBUG] Forwarding to resource [/WEB-INF/jsp/test.jsp] in InternalResourceView ‘test’
DispatcherServlet]-[DEBUG] Successfully completed request

看到這里的日志, 很多同學(xué)就奇怪了, 這里DispatcherServlet并不攔截轉(zhuǎn)發(fā)的請求[/WEB-INF/jsp/test.jsp], 就直接找到了view.

DispatcherServlet配置為’/’, 為什么不攔截*.jsp, *.jspx.的請求?

前面說的當(dāng)DispatcherServlet配置為’/’, 將會覆蓋default servlet, 將會處理所有其他Servlet都不處理的訪問請求. 所以這里不攔截?cái)r截.jsp, .jspx.的請求, 一定有其他地方攔截了該請求, 但是仔細(xì)查找web.xml并沒有發(fā)現(xiàn)其他的servlet啊!那一定是在容器中定義的啦~
果不其然, 在%TOMCAT_HOME%/conf/web.xml中繼承過來的JspServlet會處理該請求.

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

從該web.xml也看到DefaultServlet的定義了(文件中總共就定義了這兩個(gè)servlet)

     <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
           <param-name>debug</param-name>
           <param-value>0</param-value>
        </init-param>
        <init-param>
           <param-name>listings</param-name>
           <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
       <servlet-name>default</servlet-name>
       <url-pattern>/</url-pattern>
    </servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

這也就是為什么我們直接訪問不在WEB-INF的jsp, 可以直接找到并解析的原因了.
我們將test.jsp拷貝一份到webapp下, 直接訪問/test.jsp, 訪問到j(luò)sp中的內(nèi)容了.并未出現(xiàn)404, 從而驗(yàn)證了我們的猜想.

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多