Tomcat又是如何处理静态资源的

本文探讨了Tomcat如何处理静态资源,指出Tomcat作为Web容器不仅处理Servlet,还负责静态资源。通过全局配置文件web.xml中的DefaultServlet,Tomcat默认处理未映射到特定Servlet的所有请求。DefaultServlet的listings参数控制是否显示应用目录文件列表。当请求资源存在且可读时,DefaultServlet会设置响应头并读写文件内容。如果请求路径对应的是目录且listings为true,才会列出内容,否则返回404错误。

文章首发于微信公众号「Tomcat那些事儿」,欢迎关注。

我们都知道Web服务器与Web容器的区别。而且Tomcat是一种Web Container,与Nginx/Apache这一类的Web Server本质区别是,Tomcat不光可以处理静态资源,还能处理Servlet文件。

响应Servlet文件这件事,我们虽然还没有深入分析,但多少有点司空见惯的感觉了,毕竟做为一个Servlet规范的参考实现,能处理Servlet自然是情理之中的。

那Tomcat又是如何处理静态资源的呢?

可能你习惯性的打开Tomcat,部署了一个应用之后,就开始查看其运行结果,或者更多的关注Servlet内的逻辑是否正确。至于静态资源处理这个事,可能不曾留意过。

那我们一起来看看,它究竟是怎么处理的。

本质上讲,Tomcat对于所有的静态资源,会做统一处理。也就是在所有你没有配置URL匹配的地方,Tomcat这个全局统一处理的配置就开始接管工作了。

 

这时,你不禁要问,这个东西我没有配置,它怎么生效的呢?

看这里!

在Tomcat的conf目录下,就是有全局配置文件server.xml在同一个目录下,有一个web.xml,打开它之后,你会发现这样的说明:

 

The default servlet for all web applications, that serves static

resources. It processes all requests that are not mapped to other

servlets with servlet mappings.

 

再向下,你会看到关于这个全局处理的Servlet声明,如下图

它的名字叫DefaultServlet

此处,它还有一个名为listings的初始化参数,默认值为false。这个参数主要作用,是在没有welcome文件时,控制应用目录内的文件是否允许列表显示。如果设置为true,就会常见的FTP服务器一样,把应用目录下的文件都列了出来,像下面这个样子。当然,这个样式也是可以自已定义的。

 

这个DefaultServlet的servlet-mapping是这样配置的

你会不会问,既然url-pattern配置的是 ,那不就应该响应所有的请求了么?

对,我们上面说明中也提到了,是匹配所有你没定义的Servlet-mapping的请求。

而之所以自己定义的Servlet可以优先生效,则是因为Tomcat内的Servlet配置,是严格按照声明顺序初始化,并按此顺序响应请求,一层层按此比对,有一个可以响应请求,就用其处理

 

下面又到了看源码的时间了,我们来看DefaultServlet中,静态资源响应处理。

文件位于org.apache.catalina.servlets.DefaultServlet文件中。

首先是这个文件,一般资源请求,都会走GET方法。

protected void doGet(HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException {

// Serve the requested resource, including the data content

serveResource(request, response, true, fileEncoding);

}

 

serveResource这个方法内容较多,放在这里查看不太方便。大致总结下,首先会判断要请求的资源是否存在,文件是否可读,之后,根据资源的类型,设置响应头的content-type,判断文件的时间,设置超时时间等,最终是流的读写。

 

整个应用内的资源存放在resources这个变量内,声明如下:

/**

* The complete set of web application resources

*/

protected transient WebResourceRoot resources = null;

 

这块和上面内容有关联的地方是,读取文件的时候,会判断请求的路径对应的资源是否为一个文件夹,如果是目录,就会判断listings这个参数,为true时才会列出内容,否则直接返回内容找不到,即404。代码是下面这个样子。

 

 if (resource.isDirectory()) {

// Skip directory listings if we have been configured to

// suppress them

if (!listings) {

response.sendError(HttpServletResponse.SC_NOT_FOUND,

request.getRequestURI());

return;

}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值