什么是默认 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 在 webapp 启动时加载,目录列表被禁用,调试被关闭。
如果需要更改应用程序的 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:
属性Property | 说明Description |
---|---|
debug |
调试级别。除非是 tomcat 开发人员,否则它不是很有用。在撰写本文时,有用的值为 0、1、11。[0] |
listings |
如果不存在欢迎文件,是否可以显示目录列表?值可以是 true 或 false [false] 欢迎文件是 servlet api 的一部分。 警告:包含许多条目的目录列表很昂贵。对大型目录列表的多个请求可能会消耗很大一部分服务器资源。 |
precompressed |
如果存在文件的预压缩版本(原始文件旁边的文件名后附加了 |
readmeFile |
如果显示目录列表,则 readme 文件也可能随列表一起显示。此文件按原样插入,因此可能包含 HTML。 |
globalXsltFile |
如果要自定义目录列表,可以使用 XSL 转换。此值是一个相对文件名($CATALINA_BASE/conf/ 或 $CATALINA_HOME/conf/),将用于所有目录列表。这可以按上下文和/或每个目录覆盖。请参阅下面的 |
contextXsltFile |
还可以通过配置 |
localXsltFile |
还可以通过配置 localXsltFile 来按目录自定义目录列表。这必须是将要发布列表的目录中的文件,扩展名为 |
input |
读取要提供的资源时的输入缓冲区大小(以字节为单位)。[2048] |
output |
写入要提供的资源时的输出缓冲区大小(以字节为单位)。[2048] |
readonly |
此上下文是否为“只读”,因此 PUT 和 DELETE 等 HTTP 命令被拒绝?[true] |
fileEncoding |
读取静态资源时使用的文件编码。[platform default] |
useBomIfPresent |
如果静态文件包含字节顺序标记 (BOM),则应使用它来优先使用 fileEncoding 来确定文件编码。此设置必须是 |
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)现在允许部分放置。[true] |
directoryRedirectStatusCode |
进行目录重定向(尾部斜杠缺失)时,将其用作 HTTP 响应代码。[302] |
如何自定义目录列表?
可以用自己的实现覆盖 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/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 规范的 security 部分。