Skip to content

Default Servlet

Spring MVC 允许将 DispatcherServlet 映射到 /(从而覆盖容器默认 Servlet 的映射),同时仍然允许容器的默认 Servlet 处理静态资源请求。它配置了一个 DefaultServletHttpRequestHandler,其 URL 映射为 /**,且相对于其他 URL 映射具有最低优先级。

该处理程序将所有请求转发给默认 Servlet。因此,它必须保持在所有其他 URL HandlerMappings 顺序中的最后一位。如果您使用 <mvc:annotation-driven>,情况就是这样。或者,如果您设置了自己自定义的 HandlerMapping 实例,请确保将其 order 属性设置为低于 DefaultServletHttpRequestHandler 的值,后者的值为 Integer.MAX_VALUE

以下示例显示了如何使用默认设置启用该功能:

java
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}
}
kotlin
@Configuration
class WebConfiguration : WebMvcConfigurer {

	override fun configureDefaultServletHandling(configurer: DefaultServletHandlerConfigurer) {
		configurer.enable()
	}
}
xml
<mvc:default-servlet-handler/>

覆盖 / Servlet 映射的注意事项是,默认 Servlet 的 RequestDispatcher 必须通过名称而不是路径来获取。DefaultServletHttpRequestHandler 尝试在启动时自动检测容器的默认 Servlet,它使用了一份包含大多数主要 Servlet 容器(包括 Tomcat、Jetty、GlassFish、JBoss、WebLogic 和 WebSphere)已知名称的列表。如果默认 Servlet 已被自定义配置为不同的名称,或者正在使用一个默认 Servlet 名称未知的不同 Servlet 容器,则必须显式提供默认 Servlet 的名称,如下例所示:

java
@Configuration
public class CustomDefaultServletConfiguration implements WebMvcConfigurer {

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable("myCustomDefaultServlet");
	}
}
kotlin
@Configuration
class CustomDefaultServletConfiguration : WebMvcConfigurer {

	override fun configureDefaultServletHandling(configurer: DefaultServletHandlerConfigurer) {
		configurer.enable("myCustomDefaultServlet")
	}
}
xml
<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>

补充教学

1. 为什么需要这个配置?

在传统的 Web 开发中,如果你把 DispatcherServlet 拦截路径设为 /,它会接管所有请求,包括对 .js, .css, .png 等静态文件的请求。由于 DispatcherServlet 找不到对应的 @RequestMapping,就会导致 404。

开启 default-servlet-handler 后,Spring 会在找不到控制器处理时,把请求“甩”给服务器(如 Tomcat)自带的默认 Servlet 来处理,从而正确读取文件。

2. 演进历程

虽然 default-servlet-handler 很有用,但在现代 Spring 推荐方案中,使用 静态资源 (Static Resources) 才是更好的选择,因为后者支持缓存控制 (Cache-Control)、Gzip 压缩和版本化管理,而传统的 Default Servlet 功能非常单一。

Based on Spring Framework.