Tomcat处理静态文件DefaultServlet分析

问题的起因是,用网页打开tomcat7服务器上一个只有静态内容的jsp页面,里面链接了gif文件,F5刷新的时候,css和gif文件请求返回304    not  Mofified 头,而jsp请求还是返回200(想搞破坏,把jsp也可以在通过304返回头直接读取客户端缓存,但jsp是servlet只能在servlet容器中运行。。。)

因为jsp文件请求时tomcat的JspServlet处理的,而css和html、gif等静态文件默认是tomcat的DefaultServlet处理的(在tomcat配置文件conf/web.xml中有配置)。 

 先来看下tomcat7的DefaultServlet的源码:

  服务端通过resource.lookupCache(path)从服务端缓存中读取资源获得CacheEntry,如果请求资源不存在CacheEntry.exists为false,则返回404。然后通过checkIfHeaders(request, response, cacheEntry.attributes)方法根据客户端请求头的If-None-Match,If-Modified-Since来判断请求资源是否被修改,如果未被修改,则返回304头,户端直接从客户端缓存中读取资源文件。如果第一次访问或者ctrl+F5强制刷新或者资源已修改过,默认返回Etag和Last-Modified头,,告知客户端下次访问可以通过If-None-Match,If-Modified-Since比较返回304来判断是否可使用客户端缓存。还有设置文件内容,content-length,range头等,最后输出内容:

if (!checkSendfile(request, response, cacheEntry, contentLength, null))
                        copy(cacheEntry, renderResult, ostream);

如果文件超过48k,判断是否使用sendfile来输出大文件。

请求头中通过range请求部分下载,则:
                        if (!checkSendfile(request, response, cacheEntry, range.end - range.start + 1, range))
                            copy(cacheEntry, ostream, range);

protected void serveResource(HttpServletRequest request,
                                 HttpServletResponse response,
                                 boolean content)
        throws IOException, ServletException {

        boolean serveContent = content;

        // Identify the requested resource path
        String path = getRelativePath(request);
        if (debug > 0) {
            if (serveContent)
                log("DefaultServlet.serveResource:  Serving resource '" +
                    path + "' headers and data");
            else
                log("DefaultServlet.serveResource:  Serving resource '" +
                    path + "' headers only");
        }
        // 从服务端缓存中读取资源
        CacheEntry cacheEntry = resources.lookupCache(path);
        //请求资源不存在,则返回404
        if (!cacheEntry.exists) {
            // Check if we're included so we can return the appropriate
            // missing resource name in the error
            String requestUri = (String) request.getAttribute(
                    RequestDispatcher.INCLUDE_REQUEST_URI);
            if (requestUri == null) {
                requestUri = request.getRequestURI();
            } else {
                // We're included
                // SRV.9.3 says we must throw a FNFE
                throw new FileNotFoundException(
                        sm.getString("defaultServlet.missingResource",
                    requestUri));
            }

            response.sendError(HttpServletResponse.SC_NOT_FOUND,
         

你可能感兴趣的:(web,java,http,tomcat,firefox,java,缓存)