匹配根 url 并提供静态资源 [英] Match for root url and serving of static resources

查看:28
本文介绍了匹配根 url 并提供静态资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My problem is how to configure a Spring MVC application to allow at the same time

  • 应用程序应提供静态资源(css、js、图像...)
  • 根 url (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(包括根)提供服务.要服务根控制器,您可以将控制器映射到 /home(例如)并拥有一个包含 <jsp:forward page="的 /index.jsp/home"/> - 这是当前在其他框架中使用的一种方法,使用扩展映射,例如 Struts(*.do 用于旧的 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 说明 url 不是很好.

Drawbacks : having url stating with /pages is not very nice.

此解决方案在引用的页面中使用率很高.Spring DispatcherServlet 映射到 /* 并因此获取所有请求(除非存在更具体的映射).要提供静态资源,您只需声明一个 ResourceHttpRequestHandler,在 XML 中使用:

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.为此,您必须使用 "/**" 的 URL 映射和最低优先级配置 DefaultServletHttpRequestHandler.你使用 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 来服务静态(未映射)资源.不幸的是,这对于根 URL 不起作用,您必须使用 <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.

缺点:

  • 不能直接映射根 URL,需要 index.jsp <jsp:forward page="..."/> 技巧
  • 作为替换原始容器默认 servlet 的 Spring,它必须按名称调用它.它适用于常见容器(包括 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆