1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          【Tomcat】

          來源:互聯網轉載 時間:2024-01-29 07:47:05
          目錄1. Servlet 規范解讀    1.1. Use of URL Paths    1.2. Specification of Mappings2. Tomcat 源碼分析    2.1. 幾個概念    2.2. <url-pattern> 校驗規則    2.3. <url-pattern> 如何分類    2.4. <url-pattern> 分類過程    2.5. <url-pattern> 匹配過程3. 綜合示例    

          1. Servlet 規范解讀

          1.1. Use of URL Paths

          Upon receipt of a client request, the Web container determines the Web application to which to forward it. The Web application selected must have the longest context path that matches the start of the request URL.The matched part of the URL is the context path when mapping to servlets.

          The Web container next must locate the servlet to process the request using the path mapping procedure described below.

          The path used for mapping to a servlet is the request URL from the request object minus the context path and the path parameters. The URL path mapping rules below are used in order. The first successful match is used with no further matches attempted:

          1. The container will try to find an exact match of the path of the request to the path of the servlet. A successful match selects the servlet.
          2. The container will recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the ’/’ character as a path separator. The longest match determines the servlet selected.
          3. If the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that handles requests for the extension. An extension is defined as the part of the last segment after the last ’.’ character.
          4. If neither of the previous three rules result in a servlet match, the container will attempt to serve content appropriate for the resource requested. If a "default" servlet is defined for the application, it will be used. Many containers provide an implicit default servlet for serving content.

          The container must use case-sensitive string comparisons for matching.

          1.2. Specification of Mappings

          In the Web application deployment descriptor, the following syntax is used to define mappings:

          • A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
          • A string beginning with a ‘*.’ prefix is used as an extension mapping.
          • The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e., requests of the form http://host:port/<contextroot>/. In this case the path info is ’/’ and the servlet path and context path is empty string (““).
          • A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
          • All other strings are used for exact matches only.

          If the effective web.xml (after merging information from fragments and annotations) contains any url-patterns that are mapped to multiple servlets then the deployment must fail.

          2. Tomcat 源碼分析

          2.1. 幾個概念

          在分析之前簡單看下tomcat源碼中的幾個概念,Context、Wrapper、Servlet:

          • Servlet:這個很清楚,就是用來處理業務請求。
          • Wrapper:Servlet 和映射的結合,具體點就是web.xml中配置的servlet信息。
          • Context:表示一個應用,包含了 web.xml 中配置的所有信息,當一個請求到來時,它負責找到對應的Servlet,然后調用這個 Servlet 的 service 方法,執行我們所寫的業務邏輯。

          2.2. <url-pattern> 校驗規則

          org.apache.catalina.core.StandardContext.java:

          /** * Adjust the URL pattern to begin with a leading slash, if appropriate * (i.e. we are running a servlet 2.2 application).  Otherwise, return * the specified URL pattern unchanged. * * @param urlPattern The URL pattern to be adjusted (if needed) *  and returned * @return the URL pattern with a leading slash if needed */protected String adjustURLPattern(String urlPattern) {    if (urlPattern == null)        return urlPattern;    if (urlPattern.startsWith("/") || urlPattern.startsWith("*."))        return urlPattern;    if (!isServlet22())        return urlPattern;    if(log.isDebugEnabled())        log.debug(sm.getString("standardContext.urlPattern.patternWarning",                     urlPattern));    return "/" + urlPattern;}/** * Validate the syntax of a proposed <code>&lt;url-pattern&gt;</code> * for conformance with specification requirements. * * @param urlPattern URL pattern to be validated * @return <code>true</code> if the URL pattern is conformant */private boolean validateURLPattern(String urlPattern) {    if (urlPattern == null)        return false;    if (urlPattern.indexOf('n') >= 0 || urlPattern.indexOf('r') >= 0) {        return false;    }    if (urlPattern.equals("")) {        return true;    }    if (urlPattern.startsWith("*.")) {        if (urlPattern.indexOf('/') < 0) {            checkUnusualURLPattern(urlPattern);            return true;        } else            return false;    }    if ( (urlPattern.startsWith("/")) &&            (urlPattern.indexOf("*.") < 0)) {        checkUnusualURLPattern(urlPattern);        return true;    } else        return false;}/** * Check for unusual but valid <code>&lt;url-pattern&gt;</code>s. * See Bugzilla 34805, 43079 & 43080 */private void checkUnusualURLPattern(String urlPattern) {    if (log.isInfoEnabled()) {        // First group checks for '*' or '/foo*' style patterns        // Second group checks for *.foo.bar style patterns        if((urlPattern.endsWith("*") && (urlPattern.length() < 2 ||                    urlPattern.charAt(urlPattern.length()-2) != '/')) ||                urlPattern.startsWith("*.") && urlPattern.length() > 2 &&                    urlPattern.lastIndexOf('.') > 1) {            log.info("Suspicious url pattern: "" + urlPattern + """ +                    " in context [" + getName() + "] - see" +                    " sections 12.1 and 12.2 of the Servlet specification");        }    }}

          2.3. <url-pattern> 如何分類

          org.apache.catalina.mapper.Mapper.java#ContextVersion

          protected static final class ContextVersion extends MapElement<Context> {    public final String path;    public final int slashCount;    public final WebResourceRoot resources;    public String[] welcomeResources;    public MappedWrapper defaultWrapper = null;    public MappedWrapper[] exactWrappers = new MappedWrapper[0];    public MappedWrapper[] wildcardWrappers = new MappedWrapper[0];    public MappedWrapper[] extensionWrappers = new MappedWrapper[0];    ...}

          2.4. <url-pattern> 分類過程

          org.apache.catalina.mapper.Mapper.java

          /** * Adds a wrapper to the given context. * * @param context The context to which to add the wrapper * @param path Wrapper mapping * @param wrapper The Wrapper object * @param jspWildCard true if the wrapper corresponds to the JspServlet *   and the mapping path contains a wildcard; false otherwise * @param resourceOnly true if this wrapper always expects a physical *                     resource to be present (such as a JSP) */protected void addWrapper(ContextVersion context, String path,        Wrapper wrapper, boolean jspWildCard, boolean resourceOnly) {    synchronized (context) {        if (path.endsWith("/*")) {            // Wildcard wrapper            String name = path.substring(0, path.length() - 2);            MappedWrapper newWrapper = new MappedWrapper(name, wrapper,                    jspWildCard, resourceOnly);            MappedWrapper[] oldWrappers = context.wildcardWrappers;            MappedWrapper[] newWrappers = new MappedWrapper[oldWrappers.length + 1];            if (insertMap(oldWrappers, newWrappers, newWrapper)) {                context.wildcardWrappers = newWrappers;                int slashCount = slashCount(newWrapper.name);                if (slashCount > context.nesting) {                    context.nesting = slashCount;                }            }        } else if (path.startsWith("*.")) {            // Extension wrapper            String name = path.substring(2);            MappedWrapper newWrapper = new MappedWrapper(name, wrapper,                    jspWildCard, resourceOnly);            MappedWrapper[] oldWrappers = context.extensionWrappers;            MappedWrapper[] newWrappers =                new MappedWrapper[oldWrappers.length + 1];            if (insertMap(oldWrappers, newWrappers, newWrapper)) {                context.extensionWrappers = newWrappers;            }        } else if (path.equals("/")) {            // Default wrapper            MappedWrapper newWrapper = new MappedWrapper("", wrapper,                    jspWildCard, resourceOnly);            context.defaultWrapper = newWrapper;        } else {            // Exact wrapper            final String name;            if (path.length() == 0) {                // Special case for the Context Root mapping which is                // treated as an exact match                name = "/";            } else {                name = path;            }            MappedWrapper newWrapper = new MappedWrapper(name, wrapper,                    jspWildCard, resourceOnly);            MappedWrapper[] oldWrappers = context.exactWrappers;            MappedWrapper[] newWrappers = new MappedWrapper[oldWrappers.length + 1];            if (insertMap(oldWrappers, newWrappers, newWrapper)) {                context.exactWrappers = newWrappers;            }        }    }}
          • /* 結尾:wildcardWrappers
          • *. 開頭:extensionWrappers
          • /:defaultWrapper
          • 其他:extractWrappers
            • 注:包含 "" -> Context Root mapping

          2.5. <url-pattern> 匹配過程

          org.apache.catalina.mapper.Mapper.java

          /** * Wrapper mapping. * @throws IOException if the buffers are too small to hold the results of *                     the mapping. */private final void internalMapWrapper(ContextVersion contextVersion,                                      CharChunk path,                                      MappingData mappingData) throws IOException {    // ...    // Rule 1 -- Exact Match    MappedWrapper[] exactWrappers = contextVersion.exactWrappers;    internalMapExactWrapper(exactWrappers, path, mappingData);    // Rule 2 -- Prefix Match    boolean checkJspWelcomeFiles = false;    MappedWrapper[] wildcardWrappers = contextVersion.wildcardWrappers;    if (mappingData.wrapper == null) {        internalMapWildcardWrapper(wildcardWrappers, contextVersion.nesting,                                   path, mappingData);        // ...    }    // ...    // Rule 3 -- Extension Match    MappedWrapper[] extensionWrappers = contextVersion.extensionWrappers;    if (mappingData.wrapper == null && !checkJspWelcomeFiles) {        internalMapExtensionWrapper(extensionWrappers, path, mappingData,                true);    }    // Rule 4 -- Welcome resources processing for servlets    if (mappingData.wrapper == null) {        boolean checkWelcomeFiles = checkJspWelcomeFiles;        // ...    }    // ...    // Rule 7 -- Default servlet    if (mappingData.wrapper == null && !checkJspWelcomeFiles) {        if (contextVersion.defaultWrapper != null) {            mappingData.wrapper = contextVersion.defaultWrapper.object;            mappingData.requestPath.setChars                (path.getBuffer(), path.getStart(), path.getLength());            mappingData.wrapperPath.setChars                (path.getBuffer(), path.getStart(), path.getLength());            mappingData.matchType = MappingMatch.DEFAULT;        }        // ...    }    // ...}
          • 規則1:精確匹配,使用 contextVersion 的 exactWrappers
          • 規則2:前綴匹配,使用 contextVersion 的 wildcardWrappers
          • 規則3:擴展名匹配,使用 contextVersion 的 extensionWrappers
          • 規則4:歡迎頁匹配,使用 contextVersion 的welcomeResources
          • 規則7:使用默認的servlet,使用contextVersion的defaultWrapper

          3. 綜合示例

          web.xml:

          <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns="http://java.sun.com/xml/ns/javaee"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   version="2.5">  <display-name>urlpattern</display-name>  <servlet>    <servlet-name>Servlet1</servlet-name>    <servlet-class>com.Servlet1</servlet-class>  </servlet>  <servlet>    <description></description>    <servlet-name>Servlet2</servlet-name>    <servlet-class>com.Servlet2</servlet-class>  </servlet>  <servlet>    <servlet-name>Servlet3</servlet-name>    <servlet-class>com.Servlet3</servlet-class>  </servlet>  <servlet>    <servlet-name>Servlet4</servlet-name>    <servlet-class>com.Servlet4</servlet-class>  </servlet>  <servlet>    <servlet-name>Servlet5</servlet-name>    <servlet-class>com.Servlet5</servlet-class>  </servlet>  <servlet>    <servlet-name>Servlet6</servlet-name>    <servlet-class>com.Servlet6</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>Servlet1</servlet-name>    <url-pattern>/Servlet1</url-pattern>  </servlet-mapping>  <servlet-mapping>    <servlet-name>Servlet2</servlet-name>    <url-pattern>/Servlet2/*</url-pattern>  </servlet-mapping>  <servlet-mapping>    <servlet-name>Servlet6</servlet-name>    <url-pattern>/Servlet6/</url-pattern>  </servlet-mapping>  <servlet-mapping>    <servlet-name>Servlet4</servlet-name>    <url-pattern>*.foo</url-pattern>  </servlet-mapping>  <servlet-mapping>    <servlet-name>Servlet3</servlet-name>    <url-pattern>/</url-pattern>  </servlet-mapping>  <servlet-mapping>    <servlet-name>Servlet5</servlet-name>    <url-pattern></url-pattern>  </servlet-mapping></web-app>

          測試url:

          http://localhost:8080/urlpattern/Servlet2http://localhost:8080/urlpattern/Servlet2/a/b/c/dhttp://localhost:8080/urlpattern/Servlet1http://localhost:8080/urlpattern/Servlet6/http://localhost:8080/urlpattern/ServletX/l/m/n/x.foohttp://localhost:8080/urlpattern/http://localhost:8080/urlpatternhttp://localhost:8080/urlpattern/Servlet6http://localhost:8080/urlpattern/Servlet1/http://localhost:8080/urlpattern/ServletY/NOT/EXIST/

          測試結果:

          參考:

          JSR-000340 JavaTM Servlet 3.1 Final Release for Evaluation:https://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html

          標簽:urlpattern-

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          炫舞怎么得消費券?通常它 這是GM的活動。和節假日一樣,周末會有14 : 00-16 : 00在線,贈送優惠券和購物券。。。但是購物券只能和第一期q幣一起使用。在炫舞游戲里怎樣快速刷點券?:我們有三種可以拿到點卷。1.騰訊將游戲中的積分滾動獎勵設置在節假日或周末。15: 00、16: 02快速升級平刷做任務,刷明星挑戰模式,轉音樂。3.每天領工資。每天完成十場兩人以上的比賽,可以獲得日薪卷。炫舞手...

          怎么登錄青驕第二課堂?首先點擊鏈接https://www.2-class.com/competition進入清教第二課堂官方網站后,電腦用戶點擊網站第一個登錄頁面進入賬號登錄界面,手機用戶點擊我的課程進入賬號登錄界面。2-class平臺怎么注冊?點擊flash場景右上角的【注冊】按鈕,進入注冊頁面,根據頁面要求填寫注冊信息,注冊成功。注意:不支持個人注冊帳戶。所有參與者的帳號和密碼均由學校管理員提...

          成都哪家工作室拍藝術照拍的更好呢?1.木沙英花婚紗攝影工作室地址:嬌子北二路61號馮丹國際地鐵1號線金融城A出口顧客評價:能在沐沙英花拍婚紗照真的超級開心。剛到店的時候,感覺超級驚喜。給我的感覺是,只要是女生,我都會喜歡。2.八點半去照相館地址:較場壩街東方廣場B座停車場入口2單元1207室客戶評價:體驗很棒。提前兩天預約。到達當天,店家會提前打電話確認時間。到了就不用等了,馬上就可以開始化妝。3...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>