匹配根URL和提供静态资源 [英] Match for root url and serving of static resources
问题描述
我的问题是如何配置一个Spring MVC应用程序同时允许
My problem is how to configure a Spring MVC application to allow at the same time
- 应用程序应该提供静态资源(css,js) ,images ...)
- 应提供根网址(
http://my.host.org/webb_app/
)由Spring控制器
- application should serve static resources (css, js, images ...)
- the root url (
http://my.host.org/webb_app/
) should be served by a Spring controller
我已阅读如何在Spring MVC中处理静态内容?,使用Spring,在web.xml中映射到root,找不到静态资源和 Tomcat在Spring MVC应用程序上提供静态资源。所有这些都提供了可行的解决方案,直到最近,我还将它们用作烹饪配方,直到应用程序或多或少可以接受。所有这些都没有引用,也没有清楚地理解它最终起作用的原因和方式。
I've already read How to handle static content in Spring MVC?, Using Spring, mapping to root in web.xml, static resources aren't found and Tomcat serving static resources on Spring MVC app. All give working solutions, and until recently, I used any them as a cooking recipe until the application works more or less acceptably. All that without references nor a clear understanding of the why and how it finally worked.
所以问题是:为此配置Spring MVC应用程序的不同方式是什么要求,它们的缺点是什么以及它们背后的理由是什么。
So the question is : what at the different ways of configuring a Spring MVC application for this requirement, what are their drawbacks and what is the rationale behind them.
推荐答案
我将首先谈谈如何 DefaultServlet
有效。根据 Servlet 3.0规范,容器一般提供默认的servlet,它具有最低优先级并提供静态上下文。映射 /
是此默认servlet的隐式映射。
I will begin with a preliminary remark about how DefaultServlet
works. According to Servlet 3.0 specifications, containers generally provide a default servlet, that has lowest priority and serves static context. The mapping /
is the implicit mapping for this default servlet.
现在解决方案:
这是最简单的解决方案:映射Spring DispatcherServlet
到 / pages
,或到 / pages
和 / api
例如。然后,默认servlet将提供所有其他URL(包括root)。要提供根控制器,您可以将控制器映射到 / home
(例如)并具有 /index.jsp
包含< jsp:forward page =/ home/>
- 这是一种当前在其他框架中使用扩展映射的方法,如Struts( *。对于旧的Struts1执行
。
That is the easiest solution : you map Spring DispatcherServlet
to /pages
, or to /pages
and /api
for example. The default servlet will then serve all other URLs (including root). To serve root controller, you can map a controller to /home
(for example) and have a /index.jsp
containing <jsp:forward page="/home"/>
- this is a method of current use in other frameworks using extension mapping such as Struts (*.do
for old Struts1).
缺点:让网址以 / pages $ c表示$ c>不是很好。
Drawbacks : having url stating with /pages
is not very nice.
此解决方案使用率很高在引用的页面中。 Spring DispatcherServlet
映射到 / *
,因此获取所有请求(除非存在更具体的映射)。要提供静态资源,只需使用XML声明 ResourceHttpRequestHandler
:
This solution is highly used in the referenced pages. Spring DispatcherServlet
is mapped to /*
and so gets all the requests (unless a more specific mapping exists). To serve static resources, you just declare a ResourceHttpRequestHandler
, using in XML :
<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控制器直接 /
。
This works very fine, and you can map a Spring controller to /
directly.
缺点:您无法提供直接在根上下文中的静态资源。
Drawbacks : you cannot serve static resources that would be directly under root context.
映射Spring DispatcherServlet
到 /
实际上是从容器中替换默认servlet来处理所有尚未处理的URL。通过此映射,Spring可以回退到未映射到控制器的URL的原始默认servlet。要实现这一点,您必须配置 DefaultServletHttpRequestHandler
,其URL映射为/ **
且最低优先。您可以使用XML来实现:
Mapping Spring DispatcherServlet
to /
is in fact replacing the default servlet from the container to process all not already processed URLs. With this mapping, Spring can fallback to the original default servlet for URLs not mapped to controllers. For that to work, you have to configure a DefaultServletHttpRequestHandler
with a URL mapping of "/**"
and the lowest priority. You do it using 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 =.../>
首先解决方案的技巧。
That way, DispatcherServlet
normally calls all controllers, and have the original default servlet to serve static (not mapped) resources. Unfortunately, this does not work for the root URL, and you must use the <jsp:forward page="..."/>
trick like for first solution.
缺点:
- 无法直接映射root URL并需要
index.jsp
< jsp:forward page =.../>
trick - 当Spring替换原始容器的默认servlet时,必须按名称调用它。它适用于常见容器(包括Tomcat,Jetty,GlassFish,JBoss,Resin,WebLogic和WebSphere),或者您也可以将默认servlet的名称作为XML配置中的属性(
< mvc: default-servlet-handler default-servlet-name =customDefaultServlet/>
)或作为java配置的参数:configurer.enable(customDefaultServlet);
- cannot directly map root URL and need the
index.jsp
<jsp:forward page="..."/>
trick - As Spring as replaced original container default servlet, it must call it by name. It works for common containers (including Tomcat, Jetty, GlassFish, JBoss, Resin, WebLogic, and WebSphere), or you can also give the name for default servlet as an attribute in XML config (
<mvc:default-servlet-handler default-servlet-name="customDefaultServlet"/>
) or as a parameter if java configuration:configurer.enable("customDefaultServlet");
参考文献: Spring参考手册/ Web MVC框架/资源服务
这篇关于匹配根URL和提供静态资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!