Spring Boot静态资源

Spring Boot静态资源的存放位置

Spring Boot 提供了对静态资源的支持,在创建Spring Boot项目时默认只创建了一个存放静态资源的目录src/main/resources/static,其它三个如果需要可以手动创建出目录,而且这四个是有优先级,当同一个资源出现在静态目录的多个地方时是按照优先级获取的,先获取优先级高的。

  1. classpath:/META-INF/resources
  2. classpath:/resources
  3. classpath:/static
  4. classpath:/public

在这里插入图片描述

1. application.properties配置

对应的源码:spring-configuration-metadata.json

{ 
	"sourceType": "org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties", 
	"defaultValue": "\/**", 
	"name": "spring.mvc.static-path-pattern", 
	"description": "Path pattern used for static resources.", 
	"type": "java.lang.String" 
}, 
{ 
	"sourceType": "org.springframework.boot.autoconfigure.web.ResourceProperties", 
	"defaultValue": [ 
		"classpath:\/META-INF\/resources\/", 
		"classpath:\/resources\/", 
		"classpath:\/static\/", 
		"classpath:\/public\/" 
		], 
	"name": "spring.resources.static-locations", 
	"description": "Locations of static resources. Defaults to classpath:[\/META-INF\/resources\/,\n \/resources\/, \/static\/, \/public\/].",
	"type": "java.lang.String[]" },

对应application.properties的默认配置

spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/

在应用程序启动的时候会有日志打印,可以看到

  • /** 映射到 /static (或/public、/resources、/META-INF/resources)
  • /webjars/** 映射到 classpath:/META-INF/resources/webjars/在这里插入图片描述

比如 在src/main/resources/static目录下放一个index.html, 通过http://localhost:8080/index.html就能直接访问,路径中不用在包含static子路径了
如果访问静态资源想在路径上有体现,也可以自定义,如将static-path-pattern配置成spring.mvc.static-path-pattern=/static/**就需要用http://localhost:8080/static/index.html来访问
同样如果对于系统定义的静态资源的存放位置不满意也可以通过spring.resources.static-locations来定义,一般静态资源都放在src/main/resource下面

2. JavaConfig - WebMvcConfigurationSupport

addResourceHandlers用于配置spring.mvc.static-path-pattern
传统Spring MVC开发经常将jsp页面放置在webapp/WEB-INF下,这样要想访问页面就需要写一个controller对应的方法,即使方法中没什么业务逻辑,只仅仅用于页面跳转也不得不写,在Spring Boot中通过配置addViewControllers,配置一个路径和一个视图名称的映射即可,也不用再controller中写页面跳转的RequestMapping方法了
在这里插入图片描述

webjars

webjars 就是将web开发中常用的静态资源放到classpath:/META-INF/resources/webjars/ 中,然后打包成.jar发布到maven仓库中,使用时通过maven来引入,假如项目中用到jquery,常规的做法就是手动去官网下载,然后手动将bootstrap放到静态目录。一般常用的像jquery、bootstrap、angularjs、react、vue、swagger-ui等都有相应的maven依赖,目前有92个这种依赖。

<!-- jq -->
<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>jquery</artifactId>
   <version>3.3.1</version>
</dependency>

在这里插入图片描述

扫描二维码关注公众号,回复: 3604231 查看本文章

在页面上通过/webjars/jquery/3.3.1/jquery.js 来引入,Spring Boot 默认将 /webjars/** 映射到 classpath:/META-INF/resources/webjars/
可以通过http://localhost:8080/webjars/jquery/3.3.1/jquery.js来访问

webjars-locator

在上面访问静态资源时路径中包含了版本号(http://localhost:8080/webjars/jquery/3.3.1/jquery.js),假如版本升级需要全局替换所有引入的文件,webjars提供了一个webjars-locator的依赖,目的是让前端页面引入的静态资源不包含路径,当请求一个静态资源时会自动帮你映射到对的版本对应的资源

<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>webjars-locator</artifactId>
   <version>0.33</version>
</dependency>
@Controller
public class WebJarsController {

    private final WebJarAssetLocator assetLocator = new WebJarAssetLocator();

    @ResponseBody
    @RequestMapping("/webjarslocator/{webjar}/**")
    public ResponseEntity<Object> locateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) {
        try {
            // /webjarslocator/jquery/
            String mvcPrefix = "/webjarslocator/" + webjar + "/"; // This prefix must match the mapping path!
            // /webjarslocator/jquery/jquery.js
            String mvcPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
            // META-INF/resources/webjars/jquery/3.3.1/jquery.js
            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);
        }
    }

}

访问http://localhost:8080/webjarslocator/jquery/jquery.js(此地址中不包含版本号),地址映射到WebJarsController,返回META-INF/resources/webjars/jquery/3.3.1/jquery.js对应的资源。这样就达到前端引入的静态资源中不包含具体版本号,当需要升级的时候直接修改maven对应的依赖版本即可,前端也不用全局替换版本号操作了

静态资源浏览器缓存

开发时,业务对应的js经常会变动,一般浏览器会缓存静态资源,一般防止浏览器缓存静态资源的做法是在地址后面使用版本号参数,或者在地址后面使用时间戳,Spring Boot 给出了自己的解决方案

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

在这里插入图片描述
common.js放在 src/main/resources/static/js/目录下
<script src="${pageContext.request.contextPath }${urls.getForLookupPath(’/js/common.js’) }"></script>
当我们访问页面后,HTML中实际生成的代码为common-.js, 每当common.js内容发生变化时MD5值就会重新生成,当js文件没有改变时md5值不变,当js文件内容发生改变时,md5值发生变化,js文件的内容也随之改变。这样就保证了js文件始终是最新的。

Spring Boot Interceptor拦截器

拦截器的使用分两步:

  1. 声明拦截器,实现HandlerInterceptor
  2. 配置拦截器,在WebMvcConfigurerAdapter#addInterceptors配置
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(request.getRequestURI() + "-------------");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("------------postHandle------------");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("------------afterCompletion------------");
    }
}
@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {

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

        super.addResourceHandlers(registry);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
        super.addInterceptors(registry);
    }
}

访问http://localhost/index.html会被拦截,而访问http://localhost/static/index.html不会并拦截


转载
Spring Boot入门教程(十九): Thymeleaf

猜你喜欢

转载自blog.csdn.net/lolwsyzc/article/details/83106692