基于4.1.7.RELEASE
该类继承了WebContentGenerator,WebContentGenerator可以对response进行设置header,设置缓存时间等操作,并且提供了对request的method的检查功能。
ResourceHttpRequestHandler 在xml文件中的配置方法
<mvc:resources mapping="/images/**" location="/images/" />
当spring检测到这样的配置,启动时会在SimpleUrlHandlerMapping中将mapping中的值与ResourceHttpRequestHandler映射起来,当有mapping对应的请求进来时,spring会将请求转给ResourceHttpRequestHandler处理
可以通过外界来设置其需要处理的locations和resourceResovlers,主要是通过下面这两个方法
public void setLocations(List<Resource> locations) { Assert.notNull(locations, "Locations list must not be null"); this.locations.clear(); this.locations.addAll(locations); } public void setResourceResolvers(List<ResourceResolver> resourceResolvers) { this.resourceResolvers.clear(); if (resourceResolvers != null) { this.resourceResolvers.addAll(resourceResolvers); } }
从构造函数中可以看出
public ResourceHttpRequestHandler() { super(METHOD_GET, METHOD_HEAD); this.resourceResolvers.add(new PathResourceResolver()); }
在处理resourceResovlers时,默认会配置一个PathResourceResolver,如果是指定Resolvers列表,spring建议将PathResourceResolver放在列表中最后一个。那么PathResourceResolver是干什么的呢?来看看它的注释(已删除无关注释)
/** * A simple {@code ResourceResolver} that tries to find a resource under the given * locations matching to the request path. */
public class PathResourceResolver extends AbstractResourceResolver
注释里讲明了这个类会在request请求来时,根据request的path尝试在配置好的locations中寻找对应的资源。那么它是怎么判断是否是对应的资源呢?
后面ResourceResolver会讲到。
下面我们来看handlerRequest方法,这个方法会对response返回3种情况
404 : 检查请求的资源是否在配置列表中?如果请求的资源不在列表中则返回404。
304 : 请求的资源已存在配置列表中,但是请求header中的last-modified参数比资源的last-modified的时间戳新,则返回304。
返回数据 : 请求的header时间戳比资源时间戳旧,或者header中没有last-modified,那么返回正常数据并设置header缓存为1年。
@Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { checkAndPrepare(request, response, true); // 检查请求路径与资源文件对应关系 Resource resource = getResource(request); if (resource == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // check the resource's media type MediaType mediaType = getMediaType(resource); //代码已简洁 作用为log日志mediaType是否存在 // 检查时间戳 会给response设置304 if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) { logger.trace("Resource not modified - returning 304"); return; } setHeaders(response, resource, mediaType); // http method 方法 if (METHOD_HEAD.equals(request.getMethod())) { logger.trace("HEAD request - skipping content"); return; } //将资源内容写入response的outPutStream writeContent(response, resource); }