Spring Boot(十 一)-- 静态资源的访问

  还记得我们使用 SpringMVC 框架时,静态资源会被拦截,需要添加额外配置吗?我们学习了 Spring Boot 之后,那么在 Spring Boot 中的静态资源是如何处理的呢?今天小编就通过这篇文章,给大家介绍一下 Spring Boot 中的静态资源。

回顾

  我们首先回顾一下在 SSM 中是如何处理静态资源问题的。一般来说,我们可以通过<mvc:resources /> 节点来配置不拦截静态资源,如下:

<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/html/**" location="/html/"/>

但是在开发中,我们是这样配置的,上面的代码也可以像下面这样简写:

<mvc:resources mapping="/**" location="/"/>

  上面的这种配置是在 XML 中的配置,但是 SpringMVC 的配置除了在 XML 中配置,也可以在 Java 代码中配置,如果在Java代码中配置的话,我们只需要自定义一个类,继承自WebMvcConfigurationSupport 类并重写 addResourceHandlers 方法即可:

@Configuration
@ComponentScan(basePackages = "org.yexiaomo.javassm")
public class SpringMVCConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/");
    }
}

Spring Boot 中的静态资源

  在 Spring Boot 项目中,默认存在 resources/static 目录,很多朋友也知道静态资源只要放到这个目录下,就可以直接访问,那么就没有其它可以存放静态资源的位置了吗?答案肯定是有的,下面小编就给大家捋捋:
  首先我们在 WebMvcAutoConfiguration 类中看到了 SpringMVC 自动化配置的相关的内容,找到了静态资源拦截的配置,如下:

public class WebMvcAutoConfiguration {

	//下面 getResourceLocations 方法中需要添加的 "/"
	private static final String[] SERVLET_LOCATIONS = { "/" };
	
	//静态内部类
	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
		@Override
		public void addResourceHandlers(ResourceHandlerRegistry registry) {
			//用于存储静态资源的路径的变量对应的值是 “/**”
			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
			if (!registry.hasMappingForPattern(staticPathPattern)) {
				customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
						.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
						.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
			}
		}
		
		//该 getResourceLocations 方法中,又添加了“/”,
		//再加上上面this.resourceProperties.getStaticLocations() 这个方法返回了四个位置
		//因此这里返回值一共有5个
		//其中,"/" 表示 webapp 目录,即 webapp 中的静态文件也可以直接访问
		static String[] getResourceLocations(String[] staticLocations) {
			String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length];
			System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
			System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length, SERVLET_LOCATIONS.length);
			return locations;
		}
	}
}

//根据 this.resourceProperties.getStaticLocations() 这个方法返回了四个位置,如下源码:
public String[] getStaticLocations() {
	return this.staticLocations;
}

private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
		"classpath:/resources/", "classpath:/static/", "classpath:/public/" };

  根据源码的分析,我们知道 Spring Boot 中支持5个静态资源位置,同时也明白了为什么静态资源请求路径中不需要/static,因为在路径映射中已经自动的添加上了/static了。

  可能有些朋友看源码就头疼,为此下面小编就给各位举例一一分析:

分析

  首先,我们看过源码,已经知道在 Spring Boot 中,默认情况下,一共存在 5 个 位置可以存放静态资源,五个路径分别如下:

  • 1、classpath:/META-INF/resources/
  • 2、classpath:/resources/
  • 3、classpath:/static/
  • 4、classpath:/public/
  • 5、/

  前面的四个目录我们都知道,分别对应了 resources 目录下不同的目录,那么第五个 / 又是怎么理解的呢? 在 Spring Boot 项目中,默认是没有 webapp 这个目录,前面小编讲 Spring Boot 整合 Jsp 的一文中有介绍添加 webapp 目录。这里的第五个路径 / 其实就是表示 webapp 目录中的静态资源也是不被拦截的。那么,既然有了这么多可以存在的静态资源的位置,那么如果同时存在的情况,我们项目又是怎么读取的呢? 该读取的优先级就是按照上面列出的顺序。

案例一:

  系统默认创建了 classpath:/static/,正常情况,我们把自己的静态资源放到这个目录下,我们访问成功,如:我在该路径下存放一张01.jpg图片,访问:http://localhost:8080/01.jpg
在这里插入图片描述

案例二:

  下面小编将在 resources 目录下分别创建META-INF/resources/resources/public/static\四个目录里分别创建一个静态资源:
在这里插入图片描述
上面红色的文字是 test.js 对应的内容。

启动项目:
在这里插入图片描述
删除 META-INF/resources/ 目录下的 test.js,再次启动项目访问:
在这里插入图片描述
删除 resources/ 目录下的 test.js,再次启动项目访问:
在这里插入图片描述
删除 static/ 目录下的 test.js,再次启动项目访问:
在这里插入图片描述

自定义静态资源路径

  我们使用了系统默认提供的 5 个静态资源路径的位置,那么我们现在来看看自定义的静态资源路径如何配置,自定义的方式也有两种,可以通过 application.properties 来定义,也可以在 Java 代码中来定义。

application.properties 中的配置:

#该配置表示定义资源位置
spring.resources.static-locations=classpath:/
#该配置表示定义请求 URL 规则
spring.mvc.static-path-pattern=/**

小编在 resources 目录下创建了一个名为 jpg 的目录,里面放了几张图片如下:
在这里插入图片描述
启动项目,访问:http://localhost:8080/jpg/05.jpg ,这里访问路径必须要添加你创建的 jpg 路径,结果如下:
在这里插入图片描述
  这里,小编发现一个问题,就是小编从外面复制过来的图片到自定义的静态资源路径下后,重启项目,然后访问出现 404 错误,但是把项目关闭,然后打开项目,启动项目,再次访问就可以了,这里可能是开发工具的问题,无伤大雅。

  使用 Java 代码配置,这种方式和 Java 配置的 SSM 比较类似,如下:

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/yexiaomo/");
    }
}

这里的配置和上面的情况基本一致,小编就不做演示了。

注意:

  后期我们在开发时,我们会引入 Thymeleaf ,这里会有朋友将静态资源也放在 resources/templates 目录下,注意,templates 目录并不是静态资源目录,它是一个放页面模板的位置(你看到的 Thymeleaf 模板虽然后缀为 .html,其实并不是静态资源)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值