Spring Boot not serving static content

2019-01-03 01:08发布

I'm banging my head against the wall for a couple of hours now. My project is almost finished, but I can't get it to serve static content.

I've placed a folder named static under src/main/resources. Inside it I have a folder named images. When I package the app and run it, it can't find the images I have put on that folder.

I've tried to put the static files in public, resources and META-INF/resources but nothing works.

If I jar -tvf app.jar I can see that the files are inside the jar on the right folder: /static/images/head.png for example, but calling: http://localhost:8080/images/head.png, all I get is a 404

Any ideas why spring-boot is not finding this? (I'm using 1.1.4 BTW)

18条回答
Rolldiameter
2楼-- · 2019-01-03 01:47

I am using 1.3.5 and host a bunch of REST-services via Jersey implementation. That worked fine until I decided to add a couple of HTMLs + js files. None of answers given on this forum helped me. However, when I added following dependency in my pom.xml all the content in src/main/resources/static was finally showing via browser:

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

It seems spring-web / spring-webmvc is the important transitive dependency that makes spring boot auto config turn on.

查看更多
对你真心纯属浪费
3楼-- · 2019-01-03 01:49

FYI: I also noticed I can mess up a perfectly working spring boot app and prevent it from serving contents from the static folder, if I add a bad rest controller like so

 @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 the bad controller to the project, when the browser asks for a file available in static folder, the error response is '405 Method Not Allowed'.

Notice paths are not mapped in the bad controller example.

查看更多
等我变得足够好
4楼-- · 2019-01-03 01:50

I think the previous answers address the topic very well. However, I'd add that in one case when you have Spring Security enabled in your application, you might have to specifically tell Spring to permit requests to other static resource directories like for example "/static/fonts".

In my case I had "/static/css", "/static/js", "/static/images" permited by default , but /static/fonts/** was 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
    }
.....
}
查看更多
我欲成王,谁敢阻挡
5楼-- · 2019-01-03 01:52

Not to raise the dead after more than a year, but all the previous answers miss some crucial points:

  1. @EnableWebMvc on your class will disable org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration. That's fine if you want complete control but otherwise, it's a problem.
  2. There's no need to write any code to add another location for static resources in addition to what is already provided. Looking at org.springframework.boot.autoconfigure.web.ResourceProperties from v1.3.0.RELEASE, I see a field staticLocations that can be configured in the application.properties. Here's 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;
    
  3. As mentioned before, the request URL will be resolved relative to these locations. Thus src/main/resources/static/index.html will be served when the request URL is /index.html. The class that is responsible for resolving the path, as of Spring 4.1, is org.springframework.web.servlet.resource.PathResourceResolver.

  4. Suffix pattern matching is enabled by default which means for a request URL /index.html, Spring is going to look for handlers corresponding to /index.html. This is an issue if the intention is to serve static content. To disable that, extend WebMvcConfigurerAdapter (but don't 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 have fewer bugs in your code is not to write code whenever possible. Use what is already provided, even if that takes some research, the return is worth it.

查看更多
做个烂人
6楼-- · 2019-01-03 01:53

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

If your files are not in standard dirs, 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.
}
...

}

查看更多
疯言疯语
7楼-- · 2019-01-03 01:55

Did you check the Spring Boot reference docs?

By default Spring Boot will serve static content from a folder called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.

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

查看更多
登录 后发表回答