DefaultServletHttpRequestHandler是Spring MVC提供的使用Servlet容器缺省Servlet处理静态文件的HttpRequestHandler实现。
因为Spring MVC可以支持多种Servlet容器,比如Tomat,Jetty,JBoss,GlassFish,Resin,GAE,WebLogic,WebSphere等。而在这些容器中,缺省Servlet的名字又不尽相同。所以该HttpRequestHandler会运行时检测ServletContext所对应的Servlet容器的类型,从而确保无论使用哪种Servlet容器,它总是能够正确地获取到缺省Servlet并转发相应的静态文件处理请求。
实际上
Spring MVC提供了自己处理静态资源文件的机制,无论是classpath上的静态资源文件,还是文件系统中的静态资源文件,Spring MVC都有自己的处理机制。DefaultServletHttpRequestHandler的作用,主要是用在这些机制未被配置,或者开发人员主动希望通过Servlet容器缺省Servlet处理静态资源文件的情形。
源代码
package org.springframework.web.servlet.resource;
public class DefaultServletHttpRequestHandler implements HttpRequestHandler, ServletContextAware {
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish. */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
/** Default Servlet name used by Google App Engine. */
private static final String GAE_DEFAULT_SERVLET_NAME = "_ah_default";
/** Default Servlet name used by Resin. */
private static final String RESIN_DEFAULT_SERVLET_NAME = "resin-file";
/** Default Servlet name used by WebLogic. */
private static final String WEBLOGIC_DEFAULT_SERVLET_NAME = "FileServlet";
/** Default Servlet name used by WebSphere. */
private static final String WEBSPHERE_DEFAULT_SERVLET_NAME = "SimpleFileServlet";
@Nullable
private String defaultServletName;
@Nullable
private ServletContext servletContext;
/**
* Set the name of the default Servlet to be forwarded to for static resource requests.
*/
public void setDefaultServletName(String defaultServletName) {
this.defaultServletName = defaultServletName;
}
/**
* If the {@code defaultServletName} property has not been explicitly set,
* attempts to locate the default Servlet using the known common
* container-specific names.
*/
@Override
public void setServletContext(ServletContext servletContext) {
// 在ServletContext设置时猜测Servlet容器缺省的Servlet名称是什么并记录到 this.defaultServletName
this.servletContext = servletContext;
if (!StringUtils.hasText(this.defaultServletName)) {
if (this.servletContext.getNamedDispatcher(COMMON_DEFAULT_SERVLET_NAME) != null) {
this.defaultServletName = COMMON_DEFAULT_SERVLET_NAME;
}
else if (this.servletContext.getNamedDispatcher(GAE_DEFAULT_SERVLET_NAME) != null) {
this.defaultServletName = GAE_DEFAULT_SERVLET_NAME;
}
else if (this.servletContext.getNamedDispatcher(RESIN_DEFAULT_SERVLET_NAME) != null) {
this.defaultServletName = RESIN_DEFAULT_SERVLET_NAME;
}
else if (this.servletContext.getNamedDispatcher(WEBLOGIC_DEFAULT_SERVLET_NAME) != null) {
this.defaultServletName = WEBLOGIC_DEFAULT_SERVLET_NAME;
}
else if (this.servletContext.getNamedDispatcher(WEBSPHERE_DEFAULT_SERVLET_NAME) != null) {
this.defaultServletName = WEBSPHERE_DEFAULT_SERVLET_NAME;
}
else {
throw new IllegalStateException(
"Unable to locate the default servlet for serving static content. " +
"Please set the 'defaultServletName' property explicitly.");
}
}
}
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Assert.state(this.servletContext != null, "No ServletContext set");
// 获取到Servlet容器缺省Servlet的 RequestDispatcher,将请求转发给它处理。
RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName);
if (rd == null) {
throw new IllegalStateException(
"A RequestDispatcher could not be located for the default servlet '" +
this.defaultServletName + "'");
}
rd.forward(request, response);
}
}
本文介绍SpringMVC中DefaultServletHttpRequestHandler如何智能选择不同Servlet容器的默认Servlet来处理静态资源请求,适用于多种容器环境。
4万+

被折叠的 条评论
为什么被折叠?



