匹配根URL和静态资源的服务

我的问题是如何configuration一个Spring MVC应用程序允许在同一时间

  • 应用程序应该服务静态资源(CSS,JS,图像…)
  • 根url( http://my.host.org/webb_app/ )应该由Spring控制器提供

我已经阅读了如何在Spring MVC中处理静态内容? , 使用Spring,映射到web.xml中的根目录,找不到 静态资源 , Tomcat为Spring MVC应用程序提供静态资源 。 所有提供的工作解决scheme,直到最近,我用它们作为烹饪食谱,直到应用程序工作或多或less可接受。 所有这些都没有提及,也没有清楚地理解为什么以及如何最终奏效。

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

我将从关于DefaultServlet如何工作的初步评论开始。 根据Servlet 3.0规范 ,容器通常提供一个默认的servlet,它具有最低的优先级,并提供静态上下文。 mapping /是默认servlet的隐式映射。

现在解决scheme:

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

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

缺点:用/pages说明url不是很好。

将资源映射到子层次结构

该解决scheme在参考页面中被高度使用。 Spring DispatcherServlet映射到/* ,因此获得所有请求(除非存在更具体的映射)。 为了提供静态资源,你只需声明一个ResourceHttpRequestHandler ,使用XML:

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

或者在javaconfiguration中:

 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/"); } } 

这工作得很好,你可以映射一个Spring控制器到/直接。

缺点:你不能提供直接在根上下文中的静态资源。

DispatcherServlet映射为默认的servlet

将Spring DispatcherServlet映射到/实际上是从容器中replace默认的servlet来处理所有尚未处理的URL。 通过这个映射,Spring可以回退到最初的默认servlet,而不是映射到控制器的URL。 为了这个工作,你必须configuration一个DefaultServletHttpRequestHandler的URL映射"/**"和最低优先级。 你用XML来做:

 <mvc:default-servlet-handler/> 

或者在javaconfiguration中:

 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } } 

这样, DispatcherServlet通常会调用所有控制器,并使原始的默认servlet为静态(未映射)的资源提供服务。 不幸的是,这不适用于根URL,并且您必须像第一个解决scheme一样使用<jsp:forward page="..."/>技巧。

缺点 :

  • 不能直接映射根URL并需要index.jsp <jsp:forward page="..."/>窍门
  • 由于Spring取代了原来的容器默认servlet,它必须通过名称调用它。 它适用于常见的容器(包括Tomcat,Jetty,GlassFish,JBoss,Resin,WebLogic和WebSphere),或者您也可以将默认servlet的名称作为XMLconfiguration中的一个属性( <mvc:default-servlet-handler default-servlet-name="customDefaultServlet"/> )或作为参数,如果Javaconfiguration: configurer.enable("customDefaultServlet");

参考资料: Spring参考手册/ Web MVC框架/服务资源