Spring Download non-static static content

I hit my head on the wall for several hours. My project is almost complete, but I cannot get it to serve static content.

I placed the folder under static under src/main/resources . Inside, I have a folder called images . When I pack the application and run it, it cannot find the images that I placed in this folder.

I tried putting static files in public , resources and META-INF/resources , but nothing works.

If I jar -tvf app.jar, I see that the files are inside the jar in the right folder: /static/images/head.png for example, but the call: http://localhost:8080/images/head.png , that's it, what i get is 404

Any ideas why spring-boot doesn't find this? (I am using 1.1.4 BTW)

+122
spring spring-boot spring-mvc
Jul 09 '14 at 18:31
source share
18 answers

Do not raise the dead after more than a year, but all the previous answers skip some important points:

  • @EnableWebMvc on your class will disable org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration . This is great if you want complete control, but otherwise it is a problem.
  • There is no need to write code to add another place for static resources in addition to what is already provided. Looking at org.springframework.boot.autoconfigure.web.ResourceProperties with v1.3.0.RELEASE, I see a staticLocations field that can be configured in application.properties . Here is a snippet from the source:

     /** * Locations of static resources. Defaults to classpath:[/META-INF/resources/, * /resources/, /static/, /public/] plus context:/ (the root of the servlet context). */ private String[] staticLocations = RESOURCE_LOCATIONS; 
  • As mentioned earlier, the request URL will be resolved relative to these locations. This way src/main/resources/static/index.html will be used when the request URL is /index.html . The class that is responsible for resolving the path is like Spring 4.1, org.springframework.web.servlet.resource.PathResourceResolver .

  • Suffix pattern matching is enabled by default, which means the request URL is /index.html , Spring will look for handlers matching /index.html . This is a problem if the goal is static content. To disable this, extend the WebMvcConfigurerAdapter (but do not use @EnableWebMvc ) and override configurePathMatch , as shown below:

     @Override public void configurePathMatch(PathMatchConfigurer configurer) { super.configurePathMatch(configurer); configurer.setUseSuffixPatternMatch(false); } 

IMHO, the only way to reduce the number of errors in your code is to not write code when possible. Use what is already provided, even if it requires some research, the return is worth it.

+123
Nov 22 '15 at 5:45
source share

Unlike the state of spring-boot, in order to get my spring-boot jar for serving content: I had to add specially register my src / main / resources / static content through this configuration class:

 @Configuration public class StaticResourceConfiguration extends WebMvcConfigurerAdapter { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" }; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); } } 
+59
Sep 16 '14 at 21:45
source share

I had a similar problem, and it turned out that a simple solution was to extend the WebMvcAutoConfiguration configuration WebMvcAutoConfiguration :

 @Configuration @EnableWebMvc @ComponentScan public class ServerConfiguration extends WebMvcAutoConfiguration{ } 

I don't need any other code to allow my static content, but I put the directory under public under src/main/webapp and configured maven to point to src/main/webapp as the resource directory. This means that public copied to target/classes and therefore is on the classpath at runtime for spring-boot / tomcat to find.

+46
Sep 28 '14 at 18:39
source share

Look at the controllers mapped to "/" or without displaying the path.

I had such a problem, I got 405 errors, and I hit my head for a long time. The problem turned out to be the annotated controller @RestController , which I forgot to annotate with the annotation @RequestMapping . I assume that this mapped default path was "/" and blocked the mapping of the static content resource.

+21
Feb 23 '15 at 13:03
source share

Configuration can be performed as follows:

 @Configuration @EnableWebMvc public class WebMvcConfig extends WebMvcAutoConfigurationAdapter { // specific project configuration } 

It is important that your WebMvcConfig can override the addResourceHandlers method, and therefore you need to explicitly call super.addResourceHandlers(registry) (it is true that if you are happy with the default resource locations, you do not need to override any method).

Another thing that needs to be commented here is that these default resource locations ( /static , /public , /resources and /META-INF/resources ) will only be registered if there is no resource handler yet, matched with /** .

From now on, if you have an image on src/main/resources/static/images named image.jpg , for example, you can access it using the following URL: http://localhost:8080/images/image.jpg (being a server running on port 8080 and the application is deployed to the root context).

+18
Sep 21 '14 at 12:56 on
source share

Have you checked Spring download help documents ?

By default, Spring Boot will serve static content from a folder named /static (or /public or /resources or /META-INF/resources ) in the class path or from the ServletContext root.

You can also compare your project with Serving Web Content with Spring MVC, or check out the source code for spring-boot-sample-web-ui .

+11
Jul 09 '14 at 18:42
source share

I think the previous answers cover the topic very well. However, I would add that in one case, when Spring Security is enabled in your application, you may need to specify Spring to allow requests to other directories of static resources, for example, "/ static / fonts" .

In my case, I had "/ static / css", "/ static / js", "/ static / images" enabled by default, but / static / fonts / ** were blocked by my Spring security implementation.

Below is an example of how I fixed this.

 @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ..... @Override protected void configure(final HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/", "/fonts/**").permitAll(). //other security configuration rules } ..... } 
+4
Aug 02 '16 at 7:43
source share

I had this exact problem, then I realized that I defined application.properties in my application:

 spring.resources.static-locations=file:/var/www/static 

That was all I tried. In my case, I wanted to save both, so I just saved the property and added:

 spring.resources.static-locations=file:/var/www/static,classpath:static 

Which files were sent from src / main / resources / static as localhost: {port} /file.html.

None of the above worked for me, because no one mentioned this small property that could easily be copied from the Internet to serve a different purpose;)

Hope this helps! I realized that this will fit well into this long post of answers for people with this problem.

+4
Aug 14 '17 at 6:35
source share

This solution works for me:

First put the resources folder in the webapp / WEB-INF folder, following the structure

 -- src -- main -- webapp -- WEB-INF -- resources -- css -- image -- js -- ... 

Secondly, in the spring configuration file

 @Configuration @EnableWebMvc public class MvcConfig extends WebMvcConfigurerAdapter{ @Bean public ViewResolver getViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".html"); return resolver; } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resource/**").addResourceLocations("WEB-INF/resources/"); } } 

Then you can access your resource, for example http: // localhost: 8080 / resource / image / yourimage.jpg

+3
Nov 23 '15 at 19:39
source share

Two things can be considered (Spring Boot v1.5.2.RELEASE) - 1) Check all controller classes for the @EnableWebMvc annotation, delete it if there is 2) Check the controller classes for which the annotation is used - @RestController or @Controller. Do not mix Rest API behavior and MVC behavior in the same class. For MVC use @Controller and for REST API use @RestController

Doing the above 2 things solved my problem. Now my spring boot loads static resources without any problems. @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>index</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 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> 
+2
Aug 01 '17 at 16:52
source share

Just add another answer to the old question ... People mentioned that @EnableWebMvc prevent WebMvcAutoConfiguration , which is the code responsible for creating static resource handlers. There are other conditions that will also prevent WebMvcAutoConfiguration . The easiest way to see this is to look at the source:

https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ WebMvcAutoConfiguration.java # L139-L141

In my case, I have a WebMvcConfigurationSupport library in which there was a class that expanded from WebMvcConfigurationSupport which is a condition that will prevent autoconfiguration:

 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 

It’s important to never apply to WebMvcConfigurationSupport . Instead, from WebMvcConfigurerAdapter .

+2
Jun 27 '18 at 14:17
source share

If a problem occurs when starting the application from the IDE (i.e. starting with Eclipse or IntelliJ Idea) and using Maven, the key to the solution is in Spring-boot. Getting started :

If you are using Maven, do:

mvn package && java -jar target/gs-spring-boot-0.1.0.jar

The important part of which is to add a package target, which must be launched before the application is launched. (Idea: Run menu, Edit Configrations... , Add and select Run Maven Goal and specify the package target in the field)

+1
May 27 '17 at 13:44
source share

Had the same problem using gradle and eclipse and hours spent trying to figure it out.

No coding is needed, the trick is that you should use the menu option New-> Source Folder (NOT New β†’ Folder) to create a static folder in src / main / resources. I don’t know why this works, but in the new β†’ source folder, then I called the folder static (then an error appears in the dialog box of the source folder for which you should check: update the exception filters in other source folders to allow nesting). In my new static folder, I added index.html and now it works.

0
Dec 18 '14 at 12:42
source share

I use 1.3.5 and host a bunch of REST services through a Jersey implementation. This worked fine until I decided to add a couple of HTML + js files. None of the answers on this forum helped me. However, when I added the following dependency in my pom.xml, all the contents in src / main / resources / static were finally shown through the browser:

 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <dependency> 

It seems that spring -web / spring -webmvc is an important transitive dependency that activates the automatic spring boot configuration.

0
Jul 24 '16 at 17:13
source share

Well, it’s sometimes worth checking if you have redefined global mappings with some kind of rest controller. A simple example of an error (kotlin):

 @RestController("/foo") class TrainingController { @PostMapping fun bazz(@RequestBody newBody: CommandDto): CommandDto = return commandDto } 

In the above case, you will get when you request static resources:

 { title: "Method Not Allowed", status: 405, detail: "Request method 'GET' not supported", path: "/index.html" } 

The reason for this may be that you want to map @PostMapping to /foo , but forget about @RequestMapping annotations at the @RestController level. In this case, the entire request is mapped to POST and in this case you will not receive static content.

0
May 30 '18 at 7:34
source share

I am in the same situation when my spring-loaded application (integration) does not support the static contents of the folder to show the interface on localhost: 8080. Frontend is developed in angular4, so ng build which generates files in the output path dir src / main / resources / static, but does not show any content. I made a controller specifically for serving index.html, but it seems that something is disabled for spring loading to understand what angular routing information and localhost are: 8080 just displays the returned string from my controller method β€œindex.html” on the web -page. Below is index.html (I changed the default selector tag in the body, since the input component is the one I created and my main corner component is for the user interface, but still does not work, whether it's root or root):

 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Hello Test App</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-login></app-login> <script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body> </html> 

Controller Code:

 @RequestMapping("/") public String userInterface() { return "index.html"; } 

Not sure if this matters, but this is a rake-based project developed by IntellijIdea, and the spring version of the download is org.springframework.boot:spring-boot-starter-web:2.0.2.RELEASE .

@Vizcaino - As you said, there is a simple trick-, does Intellijidea make a similar option for creating the source directory / folder? I created from the context menu β†’ New β†’ directory. But not sure if this is the same, wondering if this will cause my problem?

0
03 Sep '18 at 2:23
source share

FYI: I also noticed that I could ruin a perfectly working application for loading spring and not allow it to serve contents from a static folder if I add a bad rest controller, for example,

  @RestController public class BadController { @RequestMapping(method= RequestMethod.POST) public String someMethod(@RequestParam(value="date", required=false)String dateString, Model model){ return "foo"; } } 

In this example, after adding a bad controller to the project, when the browser asks for the file available in the static folder, the error response is "405 Method Not Allowed".

In the bad controller example, there are no notification mappings.

0
Dec 01 '18 at 15:02
source share

As stated above, the file should be in $ClassPath/static/images/name.png , (/ static or / public or / resources or / META -INF / resources). This class $ ClassPath means main/resources or main/java dir.

If your files are not in the standard directory, you can add the following configuration:

 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/lib/**"); // like this } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // ... etc. } ... 

}

-one
Aug 12 '14 at 6:50
source share



All Articles