我的问题是如何配置Spring MVC应用程序同时允许
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 found和Tomcat serving static resources on Spring MVC app。所有这些都提供了有效的解决方案,直到最近,我还是将它们用作烹饪配方,直到应用程序或多或少可以接受。所有这些都没有参考,也没有清楚地理解它最终起作用的原因和方式。
所以问题是:为这个要求配置Spring MVC应用程序的不同方式是什么,它们有什么缺点以及它们背后的基本原理。
答案 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="..."/>
技巧<mvc:default-servlet-handler default-servlet-name="customDefaultServlet"/>
)中的属性或作为参数提供如果java配置:configurer.enable("customDefaultServlet");