I am using Spring Boot, and am trying to make my static resources (CSS, JS, Fonts) available when deployed. The source code is available for you to look at or clone from https://github.com/joecracko/StaticResourceError.
Right now my CSS, JS, and Font files are not visible to my deployed website.
Here is my project directory structure:
Here is the root directory of the compiled JAR: I assure you the files are present in their respective folders.
Here is the network error I am seeing:
And here are my sources provided by chrome tools. Note that bar.css appears empty here. You may look at my source code to see that it is not empty.
Here is my homepage.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
<!-- Main Styles -->
<link rel="stylesheet" href="/css/bar.css" />
<script src="/js/foo.js"></script>
</head>
<body>
<div>Welcome to Foo!</div>
</body>
</html>
Here is my Web App Initializer (FooWebAppInitializer.java)
public class FooWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ServletConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
//Spring Security
container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
dispatcher.addMapping("*.css");
dispatcher.addMapping("*.eot");
dispatcher.addMapping("*.svg");
dispatcher.addMapping("*.ttf");
dispatcher.addMapping("*.woff");
dispatcher.addMapping("*.map");
dispatcher.addMapping("*.js");
dispatcher.addMapping("*.ico");
}
}
Here is my Servlet Configuration (ServletConfig.java)
@Configuration
@EnableWebMvc
@ComponentScan({"com.foo"})
public class ServletConfig extends WebMvcAutoConfiguration{
@Bean
MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
return source;
}
}
And for kicks, My Spring Security Config (WebSecurityConfig.java)
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**"); // #3
}
}
Spring Boot comes with a pre-configured implementation of ResourceHttpRequestHandler to facilitate serving static resources. By default, this handler serves static content from any of the /static, /public, /resources, and /META-INF/resources directories that are on the classpath.
The file is located in the src/main/resources/static directory, which is a default directory where Spring looks for static content. In the link tag we refer to the main. css static resource, which is located in the src/main/resources/static/css directory. In the main.
Step 1: Move images folder from src/main/resources/static/images to src/main/webapp/WEB-INF/images. Step 2: Look up SpringBootMainApplication. java add code @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // Register resource handler for images registry.
It's not mandatory to put @SpringBootApplication to create a Spring Boot application, you can still use @Configuration and @EnableAutoConfiguration individually as shown in the example given in the next point.
Put static resources under the directory:
/src/main/resources/static
You can also use public
or resources
instead of static
as folder name.
Explanation: your build tool (Maven or Gradle) will copy all the content from /src/main/resources/
in the application classpath and, as written in Spring Boot's docs, all the content from a directory called /static
(or /public
or /resources
) in the classpath will be served as static content.
This directory could works also, but it is discouraged:
/src/main/webapp/
Do not use the src/main/webapp directory if your application will be packaged as a jar. Although this directory is a common standard, it will only work with war packaging and it will be silently ignored by most build tools if you generate a jar.
There are 2 things to consider (Spring Boot v1.5.2.RELEASE)- 1) Check all Controller classes for @EnableWebMvc annotation, remove it if there is any 2) Check the Controller classes for which annotation is used - @RestController or @Controller. Do not mix Rest API and MVC behaviour in one class. For MVC use @Controller and for REST API use @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("/")
public String home(Map<String, Object> model) {
model.put("message", this.message);
return "index";
}
}
index.html
<!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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With