没想到吧,我把html还是放到了jar包中~
public or static包下的 html 丢了(404)?
话不多说先上图
我的目录结构是这样的
src
└── main
└── java
└── com
└── example
└── demo
└── DemoApplication.java
└── resources
└── public
├── css
│ └── main.css
├── js
│ └── script.js
└── index.html
Spring Boot 默认会自动配置 /public 目录下的静态资源文件,使其可以通过 / 根路径访问。这是通过 WebMvcAutoConfiguration 类来实现的。
那么找不到文件??? 这是什么原因?
1、 先检查最基础的!! 依赖项 (理论上一定有依赖)
org.springframework.boot
spring-boot-starter-web
2、 是不是有使用 Spring Security 是否开启了静态资源 允许访问
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/public/**").permitAll() // 允许访问静态资源
.anyRequest().authenticated(); // 其他请求需要认证
}
}
3、 是不是有自主配置 WebMvcConfig 比如
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 WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/");
}
}
4、 是不是配置了yml? 自定义资源文件
spring:
resources:
static-locations: classpath:/public/
5、 是不是开启了 @EnableWebMvc !!! (我是这个原因)
使用这个注解后 会使用 WebMvcConfigurationSupport 资源加载 所以就不识别 /public /static 这些了 spring-boot 默认使用的是 WebMvcAutoConfigurationAdapter
Spring Boot 的自动配置机制
Spring Boot 使用自动配置机制来简化开发者的配置工作。对于静态资源的处理,Spring Boot 会在启动时自动配置一个 ResourceHandler 来处理这些资源。
关键类和方法
1、 WebMvcAutoConfiguration 类:
这个类是Spring Boot自动配置的一部分,负责配置Spring MVC的相关设置,包括静态资源的处理。
2、 WebMvcAutoConfiguration.AddResourceHandlers 类:
这个内部类实现了 WebMvcConfigurer 接口,并提供了 addResourceHandlers 方法来添加资源处理器。
@Configuration
@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 {
@Configuration
@ConditionalOnClass({ Servlet.class, RequestMappingHandlerMapping.class })
@ConditionalOnMissingBean({ WebMvcRegistrations.class, WebMvcConfigurationSupport.class })
@ConditionalOnBean(DispatcherServlet.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
private final ResourceProperties resourceProperties = new ResourceProperties();
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toBuilder();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.resourceProperties.getStatic().getPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
getResourceLocations(this.resourceProperties.getStatic().getResourceLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) {
// Customization can be added here if needed
}
private long getSeconds(Duration duration) {
return duration.isNegativeOrZero() ? -1 : duration.getSeconds();
}
private String[] getResourceLocations(String[] locations) {
Assert.notNull(locations, "Locations must not be null");
ArrayList resolved = new ArrayList<>(locations.length);
Arrays.stream(locations).forEach(location -> {
if (location.startsWith(CLASSPATH_PREFIX)) {
File file = getFileFromResourceLocation(location);
if (file != null && file.exists() && file.isDirectory()) {
String path = file.toURI().toString();
if (!path.endsWith("/")) {
path = path + "/";
}
resolved.add(path);
} else {
resolved.add(location);
}
} else {
resolved.add(location);
}
});
return toArray(resolved, String.class);
}
private File getFileFromResourceLocation(String location) {
try {
URL url = new UrlResource(location).getURL();
if ("file".equals(url.getProtocol())) {
return new File(url.toURI());
}
} catch (Exception ex) {
// Ignore
}
return null;
}
private T[] toArray(Collection collection, Class clazz) {
return collection.toArray((T[]) Array.newInstance(clazz, collection.size()));
}
}
}
ResourceProperties 类用于配置静态资源的路径和其他相关属性
@ConfigurationProperties(prefix = "spring.resources")
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
private boolean addMappings = true;
private Static static = new Static();
// Getters and Setters
public static class Static {
private String pathPattern = "/**";
private String[] resourceLocations = CLASSPATH_RESOURCE_LOCATIONS;
// Getters and Setters
}
}
ResourceProperties 类中的 CLASSPATH_RESOURCE_LOCATIONS 数组定义了默认的静态资源路径
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/"
};
在 WebMvcAutoConfiguration.AddResourceHandlers 类的 addResourceHandlers 方法中,Spring Boot 会自动添加一个资源处理器来处理这些默认路径下的静态资源:
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
getResourceLocations(this.resourceProperties.getStatic().getResourceLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
Spring Boot 默认会自动配置 /public 目录下的静态资源文件,使其可以通过 / 根路径访问。这是通过 WebMvcAutoConfiguration 类中的 addResourceHandlers 方法实现的。该方法会注册一个资源处理器,处理默认路径下的静态资源文件,包括 classpath:/public/。
如果你在 src/main/resources/public 目录下放置了静态资源文件,Spring Boot 会自动配置一个资源处理器来处理这些文件的请求。你可以通过以下路径访问这些文件:
http://localhost:8080/index.html 访问 src/main/resources/public/index.html
http://localhost:8080/css/main.css 访问 src/main/resources/public/css/main.css
http://localhost:8080/js/script.js 访问 src/main/resources/public/js/script.js