spring boot(10)静态资源

1 静态文件

    默认状况下,spring boot会从classpath下一个叫 /static (或 /public/resources/META-INF/resources) 的目录或者从ServletContext根目录提供静态内容。 这使用了Spring MVC的ResourceHttpRequestHandler,因此你能够经过添加本身的WebMvcConfigurerAdapter并覆写addResourceHandlers方法来改变这个行为(加载静态文件)。javascript

     在独立的web应用程序中,容器的servlet是默认开启的, 若是Spring决定不处理某些请求,默认的servlet做为一个回退(降级)将从ServletContext根目录加载内容。 大多数状况下,这不会发生(除非您修改默认的MVC配置),由于Spring老是可以经过DispatcherServlet处理请求。css

      默认状况下,静态资源映射到/**上,但你能够 经过spring.mvc.static-path-pattern 调整它。例如把全部资源迁移到/resource/**,能够用下面实现:html

spring.mvc.static-path-pattern=/resources/**

      你也能定制静态资源位置使用 spring.resources.static-locations (使用目录位置列表替换默认值)。 若是你这样作,默认的欢迎页面检测将切换到您的自定义位置。java

# 默认值为 /**
spring.mvc.static-path-pattern=
# 默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
spring.resources.static-locations=这里设置要指向的路径,多个使用英文逗号隔开

      除了上面的“标准”静态资源位置以外,还为webjar内容制做了一个特殊的例子。任何带有路径/webjar/**路径的资源都将从jar文件中提供,若是它们被打包成webjar格式。jquery

注:若是您的应用程序将打包为jar,请不要使用src/main/webapp目录。尽管这个目录是一个通用的标准,可是它只适用于war包,若是您生成一个jar,它将被大多数构建工具悄悄地忽略。web

2 配置资源映射

      Spring Boot 默认配置的/**映射到/static(或/public/resources/META-INF/resources),/webjars/**会映射到classpath:/META-INF/resources/webjars/spring

       注意:上面的/static等目录都是在classpath:下面。浏览器

   若是你想增长如/mystatic/**映射到classpath:/mystatic/,你可让你的配置类继承WebMvcConfigurerAdapter,而后重写以下方法:spring-mvc

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
		
    registry.addResourceHandler("/mystatic/**")
            .addResourceLocations("classpath:/mystatic/");
	
}

      这种方式会在默认的基础上增长/mystatic/**映射到classpath:/mystatic/,不会影响默认的方式,能够同时使用。缓存

      静态资源映射配置选项:

spring.mvc.static-path-pattern=/** # Path pattern used for static resources.

      这个配置会影响默认的/**,例如修改成/static/**后,只能映射如/static/js/sample.js这样的请求(修改前是/js/sample.js)。这个配置只能写一个值,不像大多数能够配置多个用逗号隔开的。

3 使用注意

      例若有以下目录结构:

└─resources
    │  application.yml
    │
    ├─static
    │  ├─css
    │  │      index.css
    │  │
    │  └─js
    │          index.js
    │
    └─templates
            index.ftl

      在index.ftl中该如何引用上面的静态资源呢?
      以下写法:

<link rel="stylesheet" type="text/css" href="/css/index.css">
<script type="text/javascript" src="/js/index.js"></script>

      注意:默认配置的/**映射到/static(或/public/resources/META-INF/resources)当请求/css/index.css的时候,Spring MVC 会在/static/目录下面找到。若是配置为/static/css/index.css,那么上面配置的几个目录下面都没有/static目录,所以会找不到资源文件!

因此写静态资源位置的时候,不要带上映射的目录名(如/static//public//resources//META-INF/resources/)!

4 使用WebJars

      WebJars:http://www.webjars.org/

      例如使用jquery,添加依赖:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>1.11.3</version>
</dependency>

      而后能够以下使用:

<script type="text/javascript" src="/webjars/jquery/1.11.3/jquery.js"></script>

      你可能注意到href中的1.11.3版本号了,若是仅仅这么使用,那么当咱们切换版本号的时候还要手动修改href,怪麻烦的,咱们能够用以下方式解决。

      先在pom.xml中添加依赖:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>webjars-locator</artifactId>
</dependency>

       增长一个WebJarController

@Controller
public class WebJarController {
    private final WebJarAssetLocator assetLocator = new WebJarAssetLocator();

    @ResponseBody
    @RequestMapping("/webjarslocator/{webjar}/**")
    public ResponseEntity locateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) {
        try {
            String mvcPrefix = "/webjarslocator/" + webjar + "/";
            String mvcPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
            String fullPath = assetLocator.getFullPath(webjar, mvcPath.substring(mvcPrefix.length()));
            return new ResponseEntity(new ClassPathResource(fullPath), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}

      而后使用的时候按照以下方式:

<script type="text/javascript" src="/webjarslocator/jquery/jquery.js"></script>

      注意:这里不须要在写版本号了,可是注意写url的时候,只是在原来url基础上去掉了版本号,其余的都不能少!

5 静态资源版本管理

       Spring MVC 提供了静态资源版本映射的功能。

      用途:当咱们资源内容发生变化时,因为浏览器缓存,用户本地的静态资源仍是旧的资源,为了防止这种状况致使的问题,咱们可能会手动在请求url的时候加个版本号或者其余方式。

      版本号如:

<script type="text/javascript" src="/js/sample.js?v=1.0.1"></script>

      Spring MVC 提供的功能能够很容易的帮助咱们解决相似问题。

      Spring MVC 有两种解决方式。

      注意:下面的配置方式针对freemarker模板方式,其余的配置方式能够参考。

5.1 资源名-md5 方式

      例如:

<link rel="stylesheet" type="text/css" href="/css/index-2b371326aa93ce4b611853a309b69b29.css">

      Spring 会自动读取资源md5,而后添加到index.css的名字后面,所以当资源内容发生变化的时候,文件名发生变化,就会更新本地资源。

      配置方式:

      在application.properties中作以下配置:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

      这样配置后,全部/**请求的静态资源都会被处理为上面例子的样子。

      到这儿还没完,咱们在写资源url的时候还要特殊处理。

      首先增长以下配置:

@ControllerAdvice
public class ControllerConfig {

    @Autowired
    ResourceUrlProvider resourceUrlProvider;

    @ModelAttribute("urls")
    public ResourceUrlProvider urls() {
        return this.resourceUrlProvider;
    }

}

      而后在页面写的时候用下面的写法:

<link rel="stylesheet" type="text/css" href="${urls.getForLookupPath('/css/index.css')}">

      使用urls.getForLookupPath('/css/index.css')来获得处理后的资源名。

5.2 版本号-方式

      在application.properties中作以下配置:

spring.resources.chain.strategy.fixed.enabled=true
 spring.resources.chain.strategy.fixed.paths=/js/**,/v1.0.0/**
 spring.resources.chain.strategy.fixed.version=v1.0.0

      这里配置须要特别注意,将version的值配置在paths中。缘由咱们在讲Spring MVC 处理逻辑的时候说。

      在页面写的时候,写法以下:

<script type="text/javascript" src="${urls.getForLookupPath('/js/index.js')}"></script>

      注意,这里仍然使用了urls.getForLookupPathurls配置方式见上一种方式。

      在请求的实际页面中,会显示为:

<script type="text/javascript" src="/v1.0.0/js/index.js"></script>

      能够看到这里的地址是/v1.0.0/js/index.js

5.3 静态资源版本管理-处理过程

     在Freemarker模板首先会调用urls.getForLookupPath方法,返回一个/v1.0.0/js/index.js/css/index-2b371326aa93ce4b611853a309b69b29.css

      这时页面上的内容就是处理后的资源地址。

      这以后浏览器发起请求。

      这里分开说。

      第一种md5方式

      请求/css/index-2b371326aa93ce4b611853a309b69b29.css,咱们md5配置的paths=/**,因此Spring MVC 会尝试url中是否包含-,若是包含会去掉后面这部分,而后去映射的目录(如/static/)查找/css/index.css文件,若是能找到就返回。

      第二种版本方式

      请求/v1.0.0/js/index.js。若是咱们paths中没有配置/v1.0.0,那么上面这个请求地址就不会按版本方式来处理,所以会找不到上面的资源。若是配置了/v1.0.0,Spring 就会将/v1.0.0去掉再去找/js/index.js,最终会在/static/下面找到。

本文参考

  1. http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html
  2. http://www.webjars.org/documentation
  3. http://www.mscharhag.com/spring/resource-versioning-with-spring-mvc
  4. https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources

      若是你使用的JSP或者其余模板,你能够参考上面几个连接的内容。

相关文章
相关标签/搜索