Spring MVC : 缺省 Servlet HTTP 请求处理器 DefaultServletHttpRequestHandler

DefaultServletHttpRequestHandlerSpring 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);
	}

}

你可能感兴趣的:(Spring,MVC,分析)