- /META-INF/resources/
- /resources/
- /static/
- /public/
当你打包Spring Boot项目并允许spring-boot-maven-plugin创建增强JAR后,尝试使用
java -jar my-spring-boot-project.jar
运行你的项目时,你会发现静态内容现在返回404错误。java -jar my-spring-boot-project.jar
运行你的项目时,你会发现静态内容现在返回404错误。事实证明,尽管Spring Boot很聪明地将各种资源目录添加到类路径中,但Maven没有这样做,你需要处理这一部分。默认情况下,只有src/main/resources
会被包含在JAR文件中。如果你在项目的根目录下创建一个名为/static
的文件夹(如博客文章所示),那么在使用spring-boot:run Maven目标时它将正常工作,但一旦你创建了JAR文件就不行了。
最简单的解决方案是在/src/main/resources
内部创建/static
文件夹,然后Maven会将其包含在JAR文件中。或者,你可以向Maven项目添加其他资源位置:
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>static</directory>
<targetPath>static</targetPath>
</resource>
</resources>
我希望这对某些人有用,当你回过头看Maven的工作原理时,它似乎很明显,但对于使用Spring Boot的一些人来说可能会遇到困难,因为它被设计为几乎没有配置。
// Copy resources into the jar as static content, where Spring expects it.
jar.into('static') {
from('src/main/webapp')
}
有两件事需要考虑(Spring Boot v1.5.2.RELEASE)-
1)检查所有Controller类是否有@EnableWebMvc注释,如果有则删除它
2)检查使用的控制器类的注释 - @RestController或@Controller。
不要在一个类中混合Rest API和MVC行为。对于MVC,请使用@Controller,对于REST API,请使用@RestController
Doing above 2 things resolved my issue. Now my spring boot is loading static resources with out any issues.
@Controller => load index.html => loads static files.
@Controller
public class WelcomeController {
// inject via application.properties
@Value("${welcome.message:Hello}")
private String message = "Hello World";
@RequestMapping("/welcome")
public String welcome(Map<String, Object> model) {
model.put("message", this.message);
return "welcome";
}
@RequestMapping("/")
public String home(Map<String, Object> model) {
model.put("message", this.message);
return "index";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>
<!-- The app's logic -->
<script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
<script type="text/javascript">
require.config({
paths: { text:"/webapp/libs/text" }
});
</script>
<!-- Development only -->
<script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>
</head>
<body>
</body>
</html>
@RestController
注解导致的 - 这个注解与@Controller
相同,但还会在每个方法上添加@ResponseBody
,这意味着你从控制器方法返回的任何内容都会出现在响应体中,可能会被转换器转换。在你的情况下,这可能意味着你在浏览器中看到的是作为字符串返回的“welcome”或“index”,而不是加载“welcome.html”或“index.html”视图。 - Robert HuntSpring Boot使用WebMvcAutoConfiguration
来配置静态内容,这个类只在没有自定义的WebMvcConfigurationSupport
bean时生效,在我的情况下,我确实有一个自定义的bean。
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}
那我只能自己配置了,这是我的解决方案:
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static-file/**").addResourceLocations("classpath:/static/");
}
我正在浏览一些页面,以了解如何在Spring Boot环境中提供静态内容。大多数建议是将静态文件放置在/static /resources/ src/main/webapp等位置。以下是我的想法。
允许Spring Boot自动配置Dispatcher Servlet - 确保DispatcherServletAutoConfiguration不在AutoConfiguration的排除列表中。
@EnableAutoConfiguration(exclude = { //DispatcherServletAutoConfiguration.class, })
注入外部目录以进行静态内容路由
@Value("${static-content.locations:file:C:/myprj/static/") private String[] staticContentLocations;
3.使用WebMvcConfigurerAdapter覆盖WebMvcAutoConfiguration,以建议Spring不要使用默认资源位置,而是使用我们指示的位置。就像下面这样:
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter()
{
return new WebMvcConfigurerAdapter()
{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
if (!registry.hasMappingForPattern("/**"))
{
// if this is executed spring won't add default resource
// locations - add them to the staticContentLocations if
// you want to keep them
// default locations:
// WebMvcAutoConfiguration.RESOURCE_LOCATIONS
registry.addResourceHandler("/**").addResourceLocations(
staticContentLocations);
}
}
};
}
application.properties
/application.yml
文件中将你的位置指定为spring.resources.static-locations
属性的值,甚至可以将其作为命令行参数传递。 - Robert Hunt我必须在pom.xml中添加thymeleaf依赖项。 没有这个依赖项,Spring Boot将无法找到静态资源。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
我在静态目录下有一个资产文件夹,并在扩展了WebSecurityConfigurerAdapter
的SpringConfig中进行了允许。
http.authorizeRequests().antMatchers("/", "/login", "/assets/**")
.permitAll()
我在尝试创建一个沙盒示例作为模板(https://github.com/fluentcodes/sandbox/tree/java-spring-boot)时,意外地遇到了这个404主题:我的现有工作解决方案中没有提供静态内容index.html。
由于示例相当简单,现有解决方案也能正常工作,所以我没有深入研究提到的spring解决方案。
我查看了创建的目标类,但并没有像预期的那样找到static/index.html。
原因相当简单:我将资源创建在了src/而不是src/main/下。需要一些时间来寻找,因为提到了许多复杂的解决方案。对我来说,它有一个相当琐碎的原因。
另一方面,在启动spring boot时:为什么我没有得到任何提示,表明无法找到来自location1、location2....locationx的静态内容呢?我认为这是一个话题。
<addResources>true</addResources>
配置Spring Boot插件。请参见此Stack Overflow答案https://dev59.com/nGAf5IYBdhLWcg3wVxcp - ug_