gpt4 book ai didi

java - 为什么在 Spring 中有 2 种处理静态资源的方式(addResourceHandlers 和容器的 Default Servlet")?

转载 作者:搜寻专家 更新时间:2023-11-01 03:01:04 25 4
gpt4 key购买 nike

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


选项 1:

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

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

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

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

这基本上使用 servlet 容器的“默认 Servlet”作为catch-all 来处理所有遗漏的静态资源/strong> 由 Spring 的 DispatcherServlet 实现。


选项 2:

(重写 WebMvcConfigurerAdapter 类)

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

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

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


一些与静态资源处理相关的引用:


添加 1

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

最佳答案

这是一个具体的例子,当Falling Back On the "Default" Servlet To Serve Resources不适用。

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

@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 的文档:

Note that if DefaultServletHttpRequestHandler is used, then requests will always be forwarded to the default servlet and a NoHandlerFoundException would never be thrown in that case.

的确如此。结合上述两种方法不会导致触发 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 method 的好处之一是:

  • ...从 Web 应用程序根目录以外的位置提供静态资源,包括类路径中的位置
  • cache-period 属性可用于设置远期到期 header ,以便客户端更有效地利用它们。
  • 处理程序还会正确评估 Last-Modified header (如果存在),以便适本地返回 304 状态代码,避免对已由客户端缓存的资源产生不必要的开销。

另见 this answer有关使用默认 servlet 处理静态资源如何导致不需要的副作用的更复杂示例。

关于java - 为什么在 Spring 中有 2 种处理静态资源的方式(addResourceHandlers 和容器的 Default Servlet")?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34279705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com