繁体   English   中英

为什么有两种方法可以处理Spring中的静态资源(addResourceHandlers和容器的Default Servlet“)?

[英]Why are there 2 ways to handle static resources in Spring (addResourceHandlers and the container's Default Servlet")?

我是Spring的新手。 我注意到在处理静态资源时,有两个选项:


选项1:

如果将 Spring的DispatcherServlet映射到/使用下面的代码,这使得它成为“默认Servlet”,则可以使用RequestMapping批注将某些静态资源映射到Spring处理程序(覆盖AbstractAnnotationConfigDispatcherServletInitializer类):

@Override
protected String[] getServletMappings() {
    return new String[]{"/"};
}

然后我们仍然可以启用容器的“Default Servlet”来处理那些静态资源,其URL模式不被Spring请求映射覆盖(覆盖WebMvcConfigurerAdapter类):

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

这基本上使用servlet容器的“Default Servlet”作为catch-all来处理Spring的DispatcherServlet 错过的所有静态资源。


选项2:

(重写WebMvcConfigurerAdapter类)

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    super.addResourceHandlers(registry);
    registry.addResourceHandler("*.efi").addResourceLocations("/");
}

  • 为什么有两种选择?
  • 这些方法之间的主要区别是什么?
  • 还有其他选择吗?

我通常选择2,因为我想坚持使用Spring,但我知道这不是一个强有力的理由。


一些与静态资源处理相关的参考:


添加1

似乎选项2在资源映射方面提供了更大的灵活性。 甚至可以映射WEB-INF文件夹中的资源。

下面是一个具体的例子,说明退回“默认”Servlet服务资源不适用。

这是上述方法的典型实现:

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
{
    configurer.enable();
    return;
}

但是,目前在Spring 4 处理404错误的最佳实践似乎是使用setThrowExceptionIfNoHandlerFound

@Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext)
{
    DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
    dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    return dispatcherServlet;
}

不幸的是,根据DispatcherServlet的文档:

请注意,如果使用DefaultServletHttpRequestHandler ,则请求将始终转发到默认servlet,并且在这种情况下永远不会抛出NoHandlerFoundException

的确,情况确实如此。 结合上述两种方法不会导致触发NoHandlerFoundException ,这反过来又会阻止我的404自定义错误页面解析。 现在,如果我要注释掉我的configureDefaultServletHandling方法,则抛出NoHandlerFoundException并且我的错误处理(通过@ControllerAdvice ,如链接的答案中所示)解析为我的自定义'notFoundPage'。

不幸的是,现在这意味着我的静态资源(即'default.css')没有得到解决:

DEBUG org.springframework.web.servlet.DispatcherServlet - Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name 'notFoundPage'; model is {}
org.springframework.web.servlet.NoHandlerFoundException: No handler found for GET /webapp-test/style/default.css

我认为没有办法调和这两种方法,这样它们就不会相互干扰。 我的结论是,在这种情况下,“默认Servlet”方法不适合提供静态资源,这使我们得到了addResourceHandlers方法。

使用addResourceHandlers方法的好处包括:

  • ...从Web应用程序根目录以外的位置提供静态资源, 包括类路径上的位置
  • 缓存周期属性可用于设置远期未来到期标头,以便客户端更有效地使用它们。
  • 处理程序还适当地评估Last-Modified标头(如果存在),以便适当地返回304状态代码,从而避免客户端已缓存的资源的不必要开销。

另请参阅此答案以获取更复杂的示例,说明如何使用默认servlet处理静态资源会导致不必要的副作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM