我的问题是如何配置Spring MVC应用程序以同时允许
http://my.host.org/webb_app/
我已经阅读了[如何在SpringMVC中处理静态内容?,使用Spring映射到web.xml中的根,找不到静态资源,并且Tomcat在Spring MVC应用程序上提供静态资。所有人都能提供可行的解决方案,直到最近,我还是将它们用作烹饪食谱,直到该应用程序或多或少地可以接受为止。所有这些都没有参考,也没有清楚地了解其最终原因和最终工作方式。
因此,问题是:针对此需求配置Spring MVC应用程序的不同方式是什么,它们的缺点是什么,其背后的原因是什么。
首先,我将对DefaultServlet工作原理进行初步说明。根据Servlet 3.0规范,容器通常提供默认的Servlet,该Servlet的优先级最低,并提供静态上下文。映射/是此默认Servlet的隐式映射。
DefaultServlet
/
现在为解决方案:
这是最简单的解决方案:你映射springDispatcherServlet到/pages,或者/pages和/api例如。然后,默认servlet将提供所有其他URL(包括root)。为了服务于根控制器,可以映射控制器,其/home(例如),并具有/index.jsp包含<jsp:forwardpage="/home"/>-这是在使用扩展映射如Struts其他框架当前使用(的方法*.do用于老Struts1的)。
DispatcherServlet
/pages
/api
/home
/index.jsp
<jsp:forwardpage="/home"/>
*.do
缺点:用url声明/pages不是很好。
此解决方案在参考页面中得到了广泛使用。SpringDispatcherServlet被映射到/*所有请求(除非存在更具体的映射)。要提供静态资源,您只需ResourceHttpRequestHandler在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控制器映射到。
缺点:您不能提供直接位于根上下文下的静态资源。
实际上,将Spring映射DispatcherServlet为/要替换容器中的默认servlet,以处理所有尚未处理的URL。通过这种映射,对于未映射到控制器的URL,Spring可以回退到原始的默认servlet。为此,您必须配置一个DefaultServletHttpRequestHandler具有"/**"最低优先级的URL映射。您可以使用XML进行操作:
DefaultServletHttpRequestHandler
"/**"
<mvc:default-servlet-handler/>
@Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
这样,DispatcherServlet通常会调用所有控制器,并具有原始的默认Servlet来服务静态(未映射)资源。不幸的是,这并 没有为根URL工作,你必须使用<jsp:forward page="..."/>伎俩像第一个解决方案。
<jsp:forward page="..."/>
缺点 :
index.jsp
<mvc:default-servlet-handler default-servlet-name="customDefaultServlet"/>
configurer.enable("customDefaultServlet");
参考:Spring参考手册/ Web MVC框架/资源服务