預設 Servlet 參考

目錄

預設 Servlet 是什麼

預設 servlet 是提供靜態資源以及提供目錄清單(如果啟用目錄清單)的 servlet。

它在哪裡宣告?

它在 $CATALINA_BASE/conf/web.xml 中全域宣告。以下是其宣告的預設值

    <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>

因此,預設情況下,預設 servlet 會在 Web 應用程式啟動時載入,並且會停用目錄清單並關閉偵錯。

如果您需要變更應用程式的 DefaultServlet 設定,您可以重新定義 /WEB-INF/web.xml 中的 DefaultServlet 來覆寫預設組態。然而,如果您嘗試在其他容器上部署應用程式,這將會造成問題,因為 DefaultServlet 類別將無法被辨識。您可以使用 Tomcat 特定的 /WEB-INF/tomcat-web.xml 部署描述符來解決此問題。格式與 /WEB-INF/web.xml 相同。它會覆寫任何預設設定,但不會覆寫 /WEB-INF/web.xml 中的設定。由於它是 Tomcat 特定的,因此僅在應用程式部署在 Tomcat 上時才會處理它。

我可以變更什麼?

DefaultServlet 允許以下 initParameters

屬性 說明
debug 偵錯等級。除非您是 tomcat 開發人員,否則它不太有用。截至撰寫本文為止,有用的值為 0、1、11。[0]
listings 如果沒有歡迎檔案,是否可以顯示目錄清單?值可以是 truefalse [false]
歡迎檔案是 servlet api 的一部分。
警告:列出包含許多條目的目錄會很花費資源。對大型目錄清單的多次請求可能會消耗大量的伺服器資源。
precompressed 如果存在檔案的預先壓縮版本(在原始檔案旁邊附加 .br.gz 的檔案),如果使用者代理支援相符的內容編碼(br 或 gzip)且啟用此選項,Tomcat 將提供預先壓縮的檔案。 [false]
具有 .br.gz 擴充功能的預先壓縮檔案可以直接存取,因此如果原始資源受到安全性約束保護,則必須以類似的方式保護預先壓縮的版本。
也可以設定預先壓縮格式的清單。語法是逗號分隔的 [content-encoding]=[file-extension] 對清單。例如:br=.br,gzip=.gz,bzip2=.bz2。如果指定多種格式,則用戶端支援多種格式,且用戶端未表達偏好,則格式清單的順序將被視為伺服器偏好順序,並用於選擇傳回的格式。
readmeFile 如果顯示目錄清單,也可以在清單中顯示自述檔案。此檔案會原樣插入,因此它可能包含 HTML。
globalXsltFile 如果您想要自訂您的目錄清單,您可以使用 XSL 轉換。這個值是相對檔案名稱(到 $CATALINA_BASE/conf/ 或 $CATALINA_HOME/conf/),將會用於所有目錄清單。這可以針對每個內容和/或每個目錄覆寫。請參閱下方的 contextXsltFilelocalXsltFile。xml 的格式如下所示。
contextXsltFile 您也可以透過設定 `contextXsltFile` 來自訂您的目錄清單。這必須是內容相對路徑(例如:` /path/to/context.xslt`)到具有 ` .xsl` 或 ` .xslt` 副檔名的檔案。這會覆寫 `globalXsltFile`。如果這個值存在但檔案不存在,則會使用 `globalXsltFile`。如果 `globalXsltFile` 不存在,則會顯示預設目錄清單。
localXsltFile 您也可以透過設定 `localXsltFile` 來自訂您的目錄清單。這必須是目錄中的檔案,清單將會在其中進行,且具有 ` .xsl` 或 ` .xslt` 副檔名。這會覆寫 `globalXsltFile` 和 `contextXsltFile`。如果這個值存在但檔案不存在,則會使用 `contextXsltFile`。如果 `contextXsltFile` 不存在,則會使用 `globalXsltFile`。如果 `globalXsltFile` 不存在,則會顯示預設目錄清單。
input 讀取要提供的資源時的輸入緩衝區大小(以位元組為單位)。[2048]
output 寫入要提供的資源時的輸出緩衝區大小(以位元組為單位)。[2048]
readonly 這個內容是「唯讀」的嗎?所以像 PUT 和 DELETE 等 HTTP 指令會被拒絕嗎?[true]
fileEncoding 讀取靜態資源時要使用的檔案編碼。[平台預設值]
useBomIfPresent 如果靜態檔案包含位元組順序標記 (BOM),是否應該使用這個來決定檔案編碼,而不是 fileEncoding。這個設定必須是以下之一:true(移除 BOM 並優先使用它,而不是 fileEncoding)、false(移除 BOM 但不使用它)或 pass-through(不使用 BOM 且不移除它)。[true]
sendfileSize 如果使用的連接器支援 sendfile,這代表 sendfile 將會使用的最小檔案大小(以 KiB 為單位)。使用負值來永遠停用 sendfile。[48]
useAcceptRanges 如果為 true,則會在適當時機為回應設定 Accept-Ranges 標頭。[true]
showServerInfo 當目錄清單已啟用時,是否要在傳送給客戶端的回應中顯示伺服器資訊。[true]
sortListings 伺服器是否應依目錄中的清單進行排序。 [否]
sortDirectoriesFirst 伺服器是否應在所有檔案之前列出所有目錄。 [否]
allowPartialPut 伺服器是否應將具有範圍標頭的 HTTP PUT 要求視為部分 PUT?請注意,雖然 RFC 7233 澄清範圍標頭僅對 GET 要求有效,但 RFC 9110(取代 RFC 7233)現在允許部分 PUT。 [是]

我如何自訂目錄清單?

您可以使用您自己的實作覆寫 DefaultServlet,並在您的 web.xml 宣告中使用它。如果您能理解剛剛所說的話,我們將假設您可以閱讀 DefaultServlet servlet 的程式碼並進行適當的調整。(如果不是,那麼該方法不適合您)

您可以使用 localXsltFilecontextXsltFileglobalXsltFile,而 DefaultServlet 將建立一個 xml 文件,並根據 XSLT 檔案中提供的數值執行 xsl 轉換。首先檢查 localXsltFile,然後檢查 contextXsltFile,最後檢查 globalXsltFile。如果未設定任何 XSLT 檔案,則使用預設行為。

格式

    <listing>
     <entries>
      <entry type='file|dir' urlPath='aPath' size='###' date='gmt date'>
        fileName1
      </entry>
      <entry type='file|dir' urlPath='aPath' size='###' date='gmt date'>
        fileName2
      </entry>
      ...
     </entries>
     <readme></readme>
    </listing>
  • 如果 type='dir',則不會顯示大小
  • Readme 是 CDATA 項目

以下是模擬預設 tomcat 行為的範例 xsl 檔案

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0">

  <xsl:output method="html" html-version="5.0"
    encoding="UTF-8" indent="no"
    doctype-system="about:legacy-compat"/>

  <xsl:template match="listing">
   <html>
    <head>
      <title>
        Sample Directory Listing For
        <xsl:value-of select="@directory"/>
      </title>
      <style>
        h1 {color : white;background-color : #0086b2;}
        h3 {color : white;background-color : #0086b2;}
        body {font-family : sans-serif,Arial,Tahoma;
             color : black;background-color : white;}
        b {color : white;background-color : #0086b2;}
        a {color : black;} HR{color : #0086b2;}
        table td { padding: 5px; }
      </style>
    </head>
    <body>
      <h1>Sample Directory Listing For
            <xsl:value-of select="@directory"/>
      </h1>
      <hr style="height: 1px;" />
      <table style="width: 100%;">
        <tr>
          <th style="text-align: left;">Filename</th>
          <th style="text-align: center;">Size</th>
          <th style="text-align: right;">Last Modified</th>
        </tr>
        <xsl:apply-templates select="entries"/>
        </table>
      <xsl:apply-templates select="readme"/>
      <hr style="height: 1px;" />
      <h3>Apache Tomcat/10.1</h3>
    </body>
   </html>
  </xsl:template>


  <xsl:template match="entries">
    <xsl:apply-templates select="entry"/>
  </xsl:template>

  <xsl:template match="readme">
    <hr style="height: 1px;" />
    <pre><xsl:apply-templates/></pre>
  </xsl:template>

  <xsl:template match="entry">
    <tr>
      <td style="text-align: left;">
        <xsl:variable name="urlPath" select="@urlPath"/>
        <a href="{$urlPath}">
          <pre><xsl:apply-templates/></pre>
        </a>
      </td>
      <td style="text-align: right;">
        <pre><xsl:value-of select="@size"/></pre>
      </td>
      <td style="text-align: right;">
        <pre><xsl:value-of select="@date"/></pre>
      </td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

我如何保護目錄清單?

在每個個別 webapp 中使用 web.xml。請參閱 Servlet 規範的安全性部分。