默认 Servlet 参考

目录

什么是 DefaultServlet

默认 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 的文件,该目录将显示列表。这将覆盖 globalXsltFilecontextXsltFile。如果此值存在但文件不存在,则将使用 contextXsltFile。如果 contextXsltFile 不存在,则将使用 globalXsltFile。如果 globalXsltFile 不存在,则将显示默认目录列表。
input 读取要提供服务的资源时的输入缓冲区大小(以字节为单位)。[2048]
输出 写入要提供服务的资源时的输出缓冲区大小(以字节为单位)。[2048]
只读 此上下文是否为“只读”,因此会拒绝 PUT 和 DELETE 等 HTTP 命令?[true]
文件编码 读取静态资源时使用的文件编码。[平台默认]
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 服务器是否应对目录中的列表进行排序。[false]
sortDirectoriesFirst 服务器是否应先列出所有目录,然后再列出所有文件。[false]
allowPartialPut 服务器是否应将带有 Range 标头的 HTTP PUT 请求视为部分 PUT?请注意,虽然 RFC 7233 阐明 Range 标头仅对 GET 请求有效,但 RFC 9110(已弃用 RFC 7233)现在允许部分 PUT。[true]

如何自定义目录列表?

您可以使用自己的实现覆盖 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>

如何保护目录列表?

在每个独立的 Web 应用程序中使用 web.xml。请参阅 Servlet 规范的安全部分。