匹配根URL和提供静态资源

时间:2014-10-12 13:16:43

标签: java spring-mvc resources

我的问题是如何配置Spring MVC应用程序同时允许

  • 应用程序应该提供静态资源(css,js,images ...)
  • 根网址(http://my.host.org/webb_app/)应由Spring控制器提供

我已经阅读了How to handle static content in Spring MVC?Using Spring, mapping to root in web.xml, static resources aren't foundTomcat serving static resources on Spring MVC app。所有这些都提供了有效的解决方案,直到最近,我还是将它们用作烹饪配方,直到应用程序或多或少可以接受。所有这些都没有参考,也没有清楚地理解它最终起作用的原因和方式。

所以问题是:为这个要求配置Spring MVC应用程序的不同方式是什么,它们有什么缺点以及它们背后的基本原理。

1 个答案:

答案 0 :(得分:2)

我将从DefaultServlet如何运作的初步评论开始。根据{{​​3}},容器通常提供一个默认的servlet,它具有最低优先级并提供静态上下文。映射/是此默认servlet的隐式映射。

现在解决方案:

将弹簧控制器映射到子层次结构

这是最简单的解决方案:您可以将Spring DispatcherServlet映射到/pages,或者映射到/pages/api。然后,默认servlet将提供所有其他URL(包括root)。要为根控制器提供服务,您可以将控制器映射到/home(例如)并使/index.jsp包含<jsp:forward page="/home"/> - 这是当前在其他框架中使用扩展映射的方法,例如Struts(旧版Struts1 *.do)。

缺点:让网址用/pages表示不是很好。

将资源映射到子层次结构

此解决方案在引用的页面中使用得很多。 Spring DispatcherServlet映射到/*,因此获取所有请求(除非存在更具体的映射)。要提供静态资源,只需使用XML格式声明ResourceHttpRequestHandler

<mvc:resources mapping="/resources/**" location="/public-resources/"/>

或在java配置中:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

这非常好用,您可以直接将Spring控制器映射到/

缺点:您无法提供直接位于根上下文中的静态资源。

DispatcherServlet映射为默认servlet

将Spring DispatcherServlet映射到/实际上是从容器中替换默认servlet以处理所有尚未处理的URL。通过此映射,Spring可以回退到未映射到控制器的URL的原始默认servlet。为此,您必须配置DefaultServletHttpRequestHandler,其URL映射为"/**"且优先级最低。您可以使用XML执行此操作:

<mvc:default-servlet-handler/>

或在java配置中:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

}

这样,DispatcherServlet通常会调用所有控制器,并拥有原始的默认servlet来提供静态(未映射)资源。不幸的是,对于根网址,工作,您必须使用<jsp:forward page="..."/>技巧作为第一个解决方案。

缺点:

  • 无法直接映射根网址,需要index.jsp <jsp:forward page="..."/>技巧
  • 当Spring替换原始容器的默认servlet时,必须按名称调用它。它适用于常见容器(包括Tomcat,Jetty,GlassFish,JBoss,Resin,WebLogic和WebSphere),或者您也可以将默认servlet的名称作为XML配置(<mvc:default-servlet-handler default-servlet-name="customDefaultServlet"/>)中的属性或作为参数提供如果java配置:configurer.enable("customDefaultServlet");

参考文献:Servlet 3.0 specifications