Tomcat's Catalina 6-DefaultServlet and JspServlet

Welcome everyone to pay attention to  github.com/hsfxuebao  , I hope it will be helpful to you. If you think it is possible, please click Star.

Tomcat $CATALINA_BASE/conf/web.xmldefines two servlets by default in: DefaultServlet和JspServlet, and because $CATALINA_BASE/conf/web.xml为Web应用的默认部署描述文件of that, these two servlets exist by default in all web application containers. Its specific configuration is as follows:

<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>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- The mappings for the JSP servlet -->
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>
复制代码

1. DefaultServlet

As can be seen from the previous configuration, DefaultServlet url-pattern为“/”, therefore, it will be used as the default Servlet. 当客户端请求不能匹配其他所有Servleth时,将由该Servlet处理.

DefaultServlet is mainly used to process static resources, such as HTML, pictures, CSS, JS files, etc., and to 提升服务器性能,Tomcat对访问文件进行了缓存. Follow 默认配置,客户端请求路径与资源的物理路径是一致的. That is, when the link we input http:/127.0.0.1:8080/myapp/static/sample.pngis , the physical path of the loaded image is$CATALINA BASE/webapps/myapp/static/sample.png

Of course, if we want DefaultServlet to only load resources in the static directory, we only need 将url-pattern改为“/static/*”即可(at this point, DefaultServlet will no longer be the default Servlet). However, this does not change our request path, which means that the resource still points to its physical path, because DefaultServlet fetches the file based on the full request address instead of the relative path based on the servlet.

If we want the web application to override Tomcat's DefaultServlet configuration, we only need to add "/" to the url-pattern of the custom servlet (at this point, the custom servlet will become the default servlet).

  • 覆盖DefaultServlet配置时要慎重,因为这可能导致无法加载静态文件,除非在覆盖的情况下,自定义Servlet可以兼容DefaultServlet的功能以及对请求地址的处理(大多数Servlet基于相对路径来分发请求,而非完整路径。此时如果直接覆盖,将导致客户端请求无效)。

  • 当然,我们应该尽量避免使不同Servlet之间产生覆盖,因为覆盖结果会与具体的加载顺序(web.xml、web-fragment.xml以及注解顺序)相关,当系统复杂度上升时,可维护性势必会降低。建议通过划分Servlet请求目录(如:/static以、html/、js/等)指定请求扩展名(如:*.do、*action)来合理管理请求路径命名。

DefaultServlet除了支持访问静态资源,还支持查看目录列表,只需要将名为“listings”的init-param设置为true。此时如果我们输入http://127.0.0.1:8080/myapp/static/, 且该目录下没有任何欢迎文件(welcome-file-list配置),Tomcat将返回对应物理目录下的文件目录列表。

需要确保welcome-file-list不包含虚拟的文件名,如index.do,否则此时仍会由index.do匹

配的Servlet处理。

默认情况下,Tomcat以HTML的形式输出文件目录列表(包括文件名、大小、最后修改时间)。此外,可以通过参数 localXsltFi1e、contextXsltFile或globalXsltFile指定一个XSL或XSLT文件。此时,Tomcat将以XML形式输出文件目录,并使用指定的XSL或XSLT文件将其转换为响应输出。通过这种方式,我们可以根据需要定制文件目录输出界面。

Tomcat输出的XML内容格式如下:

<?xml version='1.0?>
<listing contextPath='web应用根目录'directory='当前查看目录'hasParent='true>
    <entries>
        <entry type='file'urlPath='文件路径'size='文件大小'date='最后修改时间'>文件名</entry>
        <entry type='dir'urlPath=:'子目录路径'date='最后修改时间'>目录名</entry>
    </entries>
</listing>
复制代码

XSL及XSLT相关知识参见http:/www.w3.org/TR/xslt。

DefaultServlet支持的初始化参数如表所示,我们可以根据实际需要进行配置。

参数 描述
debug Dbug日志级别,主要用于开发环境。当前版本只有0、1~10、≥11这3个级别,而且同一级别内的值无论配置为何都是等价的
listings 如果配置为tue,当请求目录下没有欢迎文件时,将显示文件目录列表,默认为false。如果目录下包含过多子目录和文件,该操作非常耗费性能,在请求访问量大的情况下占用大量系统资源
readmeFile ReadMe文件名。当DefaultServlet允许显示文件目录,且当前文件目录下存在readmeFile指定的文件时,该文件将会被插入到最终的请求响应,以显示当前目录的ReadMe信息
globalXsltFile Tomcat支持通过XSL定制文件目录显示列表,该参数用于指定XSL文件(基于 C A T A L I N A B A S E / c The n f or CATALINA_BASE/conf或 CATALINA_HOME/conf的相对路径),因此XSL文件可以在所有Web应用中共享
contextXsltFile 作用与globalXsltFi1e相同,但是文件路径相对于Wcb应用根目录,因此该参数指定的文件只用于具体的Web应用
localXsltFile 作用与globalXs.1tFi1e相同,但是文件路径相对于当前请求目录,因此该参数指定的文件只适用于当前请求目录。Tomcat{优先使用该参数,其次为contextXsltFile,globalXs1tFi1e优先级最低
input 读资源文件时,输人缓冲大小,单位为字节,默认为2048
output 写资源文件时,输出缓冲大小,单位为字节,默认为2048
readonly 如果配置为tue,Tomcat将会拒绝由DefaultServlet处理的PUT和DELETE请求
fileEncoding 读取资源文件时使用的文件编码
sendfilesize 如果当前连接器支持sendfile,该参数用于配置使用sendfile的最小文件大小,单位为KB。如果为负数,表示禁用sendfile
useAcceptRanges 如果为true,将添加Accept--Rangesp响应头
showServerInfo 如果为tue,将会在文件目录列表中输出服务器信息,当前版本只适用于默认格式输出的情况

2. JspServlet

默认情况下,JspServlet的url-pattern为*.jsp和*.jspx,因此它负责处理所有JSP文件的请求。

JspServlet主要完成以下工作。

  • 根据JSP文件生成对应Servlet的JAVA代码(JSP文件生成类的父类为org,apache.jasper.runtime.Http]spBase-一实现了Servlet接口)

  • 将JAVA代码编译为JAVA类。Tomcat支持Ant和JDT(Eclipse提供的编译器)两种方式编译JSP类,默认采用JDT。

  • 构造Servlet类实例并执行请求。

Tomcat默认配置的JspServlet,不仅用于处理SP文件,还用于配置指向单文件的Servlet。单文件的Servlet示例如下:

<servlet>
    <servlet-name>sample</servlet-name>
    <jsp-file>/sample/index.jsp</jsp-file>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>sample</servlet-name>
    <url-pattern>*.x</url-pattern>
</servlet-mapping>
复制代码

我们并没有指定servlet-class,而是增加了jsp-file,使其指向一个JSP文件。该Servlet处理所有扩展名为“*x”的请求

If Tomcat specifies jsp-file, it will automatically set the servlet-class to JspServlet, and add the initialization parameters set in the default JspServlet to the current servlet.

Reference article

tomcat-9.0.60-src source code analysis 
Tomcat architecture analysis

Guess you like

Origin juejin.im/post/7084580465205575717