默认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 | 如果没有欢迎文件,是否可以显示目录列表?值可以是true或false。[false] 欢迎文件是servlet API的一部分。 警告:包含许多条目的目录列表开销很大。对大型目录列表的多次请求可能会消耗大量服务器资源。 |
precompressed | 如果存在文件的预压缩版本(文件名追加了.br 或.gz 且与原始文件位于同一位置的文件),Tomcat将在用户代理支持相应的content encoding(br或gzip)且此选项启用时,提供预压缩文件。[false]如果直接请求,带有 .br 或.gz 扩展名的预压缩文件将可访问,因此如果原始资源受到安全约束的保护,预压缩版本也必须同样受到保护。还可以配置预压缩格式列表。语法是逗号分隔的 [content-encoding]=[file-extension] 对。例如:br=.br,gzip=.gz,bzip2=.bz2 。如果指定了多种格式,并且客户端支持不止一种且未表达偏好,则格式列表的顺序将被视为服务器偏好顺序,并用于选择返回的格式。 |
readmeFile | 如果显示目录列表,可能还会随列表一同显示一个readme文件。此文件按原样插入,因此可能包含HTML。 |
globalXsltFile | 如果您希望自定义目录列表,可以使用XSL转换。此值是一个相对文件名(相对于$CATALINA_BASE/conf/或$CATALINA_HOME/conf/),将用于所有目录列表。这可以按上下文和/或按目录覆盖。请参阅下面的contextXsltFile和localXsltFile。xml的格式如下所示。 |
contextXsltFile | 您还可以通过配置contextXsltFile 按上下文自定义目录列表。这必须是到带有.xsl 或.xslt 扩展名的文件的上下文相对路径(例如:/path/to/context.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] 已弃用。此选项将在Tomcat 12及更高版本中移除,且不提供替代品,届时它将有效地硬编码为 true 。 |
showServerInfo | 当启用目录列表时,是否应在发送给客户端的响应中显示服务器信息。[true] |
sortListings | 服务器是否应对目录中的列表进行排序。[false] |
sortDirectoriesFirst | 服务器是否应在所有文件之前列出所有目录。[false] |
allowPartialPut | 服务器是否应将带有Content-Range头的HTTP PUT请求视为部分PUT?请注意,虽然RFC 7231澄清了带有Content-Range头的PUT请求是错误请求,但RFC 9110(它废除了RFC 7231)现在允许部分PUT。[true] |
directoryRedirectStatusCode | 当发生目录重定向(缺少尾随斜杠)时,使用此值作为HTTP响应代码。[302] |
allowPostAsGet | 控制是否将使用POST方法对静态资源发出的直接请求(即不是转发或包含)作为使用GET方法处理。如果不允许,则请求将被拒绝。将请求作为使用GET方法处理的默认行为保持不变。[true] |
如何自定义目录列表?
您可以使用自己的实现来覆盖DefaultServlet,并在您的web.xml声明中使用它。如果您能理解刚刚所说的内容,我们将假定您可以阅读DefaultServlet servlet的代码并进行适当的调整。(如果不能,那么该方法不适合您)
您可以使用localXsltFile
、contextXsltFile
或globalXsltFile
,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'
,则缺少size - 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/11.0</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>