17.Web静态资源访问规则

 

Web静态资源访问规则

1. springboot访问静态资源默认目录

  1. src/main/resources/static
  2. src/main/resources/public
  3. src/main/resources/resources
  4. src/main/resources/META-INF/resources

优先级:

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

测试方法:

1.新建目录和index.html页面

index.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
/META-INF/resources/index.html
</body>
</html>

2.运行启动类,在浏览器中访问index.html

2. 自定义静态文件配置的方式

1.创建资源目录及资源文件

1
2
3
src/main/resources/myPage/index.html
src/main/resources/myResource/index.html
src/main/resources/testResource/index.html
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
/myResource/index.html
</body>
</html>

2.创建配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebConfig implements WebMvcConfigurer{

/**
* 注册静态资源地址
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 第一个参数: url访问的地址
* 第二个参数: 当有匹配到这个url之后指定访问项目的资源目录,放在前面的参数优先级高
*/
registry.addResourceHandler("/test1/**").addResourceLocations("classpath:myResource/", "classpath:myPage/");
registry.addResourceHandler("/test2/**").addResourceLocations("classpath:testResource/");
}
}

3.打开浏览器

http://localhost:8080/test1/index.html

http://localhost:8080/test2/index.html

3. 默认的那四个目录怎么配置的呢

WebMvcAutoConfiguration -> 静态内部类EnableWebMvcConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package org.springframework.boot.autoconfigure.web.servlet;

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

/**
* The default Spring MVC view prefix.
*/
public static final String DEFAULT_PREFIX = "";

/**
* The default Spring MVC view suffix.
*/
public static final String DEFAULT_SUFFIX = "";

private static final String SERVLET_LOCATION = "/";

/**
* Configuration equivalent to {@code @EnableWebMvc}.
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
ServletContext servletContext = getServletContext();
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
// private String staticPathPattern = "/**";
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
// private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
// private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
}
});
}

private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
}

private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
Consumer<ResourceHandlerRegistration> customizer) {
if (registry.hasMappingForPattern(pattern)) {
return;
}
ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
customizer.accept(registration);
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
customizeResourceHandlerRegistration(registration);
}

}
}

addResourceHandler()的参数this.mvcProperties.getStaticPathPattern()

addResourceLocations()的参数this.resourceProperties.getStaticLocations()

4. webjars的访问配置

什么是webjars

Maven里面可以对html js css 图片等打jar包

引入jquery的jar包

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.webjars.bower/jquery -->
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>

启动项目

浏览器访问: http://localhost:8080/webjars/jquery/3.6.0/dist/jquery.js

为什么以上的地址可以被访问?

WebMvcAutoConfiguration -> 静态内部类EnableWebMvcConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package org.springframework.boot.autoconfigure.web.servlet;

public class WebMvcAutoConfiguration {

public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
ServletContext servletContext = getServletContext();
// 配置webjars
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
}
});
}

private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
}

private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
Consumer<ResourceHandlerRegistration> customizer) {
if (registry.hasMappingForPattern(pattern)) {
return;
}
ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
customizer.accept(registration);
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
customizeResourceHandlerRegistration(registration);
}

}
}
1
2
3
4
5
// "/webjars/**": 表示匹配访问url
// "classpath:/META-INF/resources/webjars/": 表示资源所在路径
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");

private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {}

http://localhost:8080/webjars/jquery/3.6.0/dist/jquery.js中的webjars对应"/webjars/**"http://localhost:8080/webjars/表明访问"classpath:/META-INF/resources/webjars/"目录下的资源。

http://localhost:8080/webjars/jquery/3.6.0/dist/jquery.js中的jquery/3.6.0/dist/jquery.js对应资源路径。