为什么有两种方法来处理Spring中的静态资源(addResourceHandlers和容器的默认Servlet)? [英] Why are there 2 ways to handle static resources in Spring (addResourceHandlers and the container's Default Servlet")?

查看:7921
本文介绍了为什么有两种方法来处理Spring中的静态资源(addResourceHandlers和容器的默认Servlet)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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






选项1:



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

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

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

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



这基本上使用servlet容器的Default Servlet作为 em 处理所有静态资源






选项2:



(覆盖 WebMvcConfigurerAdapter 类)

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







    < b $ b


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






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








ADD 1



看起来选项2提供了更多的灵活性关于资源映射。甚至可以映射 WEB-INF 文件夹中的资源。

解决方案

这里是一个具体的例子,当回退到默认Servlet服务资源不适用。



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

  @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;不幸的是,根据的文档 docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html#setThrowExceptionIfNoHandlerFound-boolean-rel =nofollow noreferrer> DispatcherServlet


请注意,如果 DefaultServletHttpRequestHandler ,则请求
将始终转发到默认servlet和
NoHandlerFoundException 永远不会被抛出。


事实上,是这样的。结合上述两种方法不会导致触发 NoHandlerFoundException ,这反过来又会阻止我的404自定义错误页面解析。现在,如果我注释掉我的 configureDefaultServletHandling 方法,将抛出 NoHandlerFoundException ,并且我的错误处理不幸的是,现在这意味着我的自定义的'notFoundPage'是一个非常简单的方法,如下所示:c $ c> @ControllerAdvice 静态资源(即'default.css')未解决:

  DEBUG org.springframework.web.servlet.DispatcherServlet  - 处理程序执行导致异常 - 转发到已解决的错误视图:ModelAndView:对名称为'notFoundPage'的视图的引用; model is {} 
org.springframework.web.servlet.NoHandlerFoundException:找不到GET的处理程序/webapp-test/style/default.css

我没有看到任何方法来协调这两种方法,以便它们不会相互干扰。我的结论是,Default Servlet方法不适合在这种情况下提供静态资源,这使我们有 addResourceHandlers 方法。



使用 addResourceHandlers 方法是:




  • ...从网络应用程序根以外的位置(包括类路径上的位置)提供静态资源。

  • cache-period属性可以是

  • 处理程序还正确地评估Last-Modified标头(如果存在),以便304状态代码将适当地返回,避免客户端已经缓存的资源的不必要开销。


I am new to Spring. I noticed that when handling static resources, there are two options available:


Option 1:

If Spring's DispatcherServlet is mapped to / with the below code, which makes it the "Default Servlet", it's possible to map certain static resources to Spring handlers with RequestMapping annotation (overriding the AbstractAnnotationConfigDispatcherServletInitializer class):

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

Then we can still enable the container's "Default Servlet" to handle those static resources whose URL pattern is not covered by Spring request mapping (overriding the WebMvcConfigurerAdapter class):

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

This basically uses the servlet container's "Default Servlet" as the catch-all to handle all the static resources missed by Spring's DispatcherServlet.


Option 2:

(overriding the WebMvcConfigurerAdapter class)

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


  • Why are there two options?
  • What are the main differences between these approaches?
  • Are there any other options?

I usually take option 2 because I want to stick to Spring, but I know that's not a strong reason.


Some reference related to static resources handling:


ADD 1

It seems option 2 provides much more flexibility regarding the resource mapping. And even resources within WEB-INF folder can be mapped.

解决方案

Here is a concrete example of when Falling Back On the "Default" Servlet To Serve Resources is not applicable.

This is a typical implementation of the above approach:

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

However, the current best practice for handling 404 errors in Spring 4 appears to be to use setThrowExceptionIfNoHandlerFound:

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

Unfortunately, according to the documentation for 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.

Indeed, this is the case. Combining both of the above approaches does not result in a NoHandlerFoundException being triggered, and this in turn prevents my 404 custom error page from resolving. Now, if I were to comment out my configureDefaultServletHandling method, the NoHandlerFoundException is thrown and my error handling (via @ControllerAdvice as shown in the linked answer) resolves to my custom 'notFoundPage'.

Unfortunately, this now means that my static resources (i.e., 'default.css') are not resolved:

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

I do not see any way to reconcile these two approaches so that they will not interfere with each other. My conclusion is that the "Default Servlet" approach is not appropriate for serving static resources in this case, which leaves us with the addResourceHandlers method.

Among the benefits of using the addResourceHandlers method are:

  • ...serve static resources from locations other than the web application root, including locations on the classpath.
  • The cache-period property may be used to set far future expiration headers so that they will be more efficiently utilized by the client.
  • The handler also properly evaluates the Last-Modified header (if present) so that a 304 status code will be returned as appropriate, avoiding unnecessary overhead for resources that are already cached by the client.

这篇关于为什么有两种方法来处理Spring中的静态资源(addResourceHandlers和容器的默认Servlet)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆