Spring boot访问js、css、图片(img)访问404无法访问的问题

问题: 今天在使用spring boot的时候,我按照spring boot的要求将css、js、图片放在规定的/src/main/resource/public/js下面,却怎么也访问不到,报的是404错误,在查找资料无果后,经过反复的实验,终于找到了问题的解决方法.

首先网上的解决方法千篇一律的都是怎么使用spring boot static content,一点有价值的信息也没有。偶尔有几个老外遇到了404的问题,也是因为他的资源放错了目录,有的放到了templates下面,有的直接放到了resource下面,这跟我遇到的情况都不相同。

我的目录结构如下:

mulu

按照道理来说,是没问题的,但是访问时候却是404,我好奇怪,于是将public改成static,还是不行。

接着,我从spring boot的官网,重新生成了一个新的项目,也是添加的这样的目录结构,访问确实正常的,那么就可以肯定是某个地方配置或者是冲突导致的,我先怀疑是引入的某个jar包导致的冲突,尤其是mybatis的引入,以及@MapperScan("huster.top.mapper")的配置(具体原因是因为观察到info信息)于是我将正常的pom.xml拷贝过去,结果不行,把MapperScan去掉也不行,把ComponentScan也同时去掉还是不行...

然后我观察到正常的时候,有输出这样的info信息:

2016-12-05 21:57:05.395 INFO 91962 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-05 21:57:05.396 INFO 91962 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-05 21:57:06.119 INFO 91962 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]

 

然而在不正常的工程里,却没有这个信息,那么为什么没有加载SimpleUrlHandlerMapping这个类的里面的registerHandlers方法,为啥呢。然后我发现registerHandlers是被initApplicationContext方法调用的,那么为什么SimpleUrlHandlerMapping这个类就没有在被初始化列表里呢?什么时候才会调用这个类呢?这让我想起了注册static目录的一配置方法,代码如下:

然后我添加了如下的代码,

package huster.top.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.io.File;

/**
 */
@Configuration
public class StaticResourceConfiguration  extends WebMvcConfigurerAdapter {

    private static final String[] RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    Logger logger = LoggerFactory.getLogger(StaticResourceConfiguration.class);
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        try {
            File directiory = new File("");
            logger.info(directiory.getCanonicalPath());
            registry.addResourceHandler("/**").addResourceLocations(RESOURCE_LOCATIONS).addResourceLocations("file:" + directiory.getCanonicalPath() + "/");
        } catch (Exception e) {

        }
    }
}

上面的代码一加,果然就可以了,但是我始终想不通问题出在哪里,一定是我加了什么多余的配置,导致了资源文件访问不到的问题,应该删除代码才对,而不是加代码。

这个时候我的思路转向了查找为什么SimpleUrlHandlerMapping这个类没有被加载的问题上,然而spring boot的源码太大了,不是一时半会能看完的,所以我还是以删除代码尝试为主。

在经过以上尝试以后,我突然想到了我增加的一个解决跨域问题的一个配置上面,这个是为了解决ajax访问跨域问题的

Cross-origin resource sharing (CORS) is a W3C specification implemented by most browsersthat allows you to specify in a flexible way what kind of cross domain requests are authorized, instead of using some less secured and less powerful hacks like IFrame or JSONP.

我参考的是这篇文章: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

 

我的代码如下:

 

package huster.top.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * Created by longan.rtb on 16/7/1.
 * 全局配置
 */
@Configuration
@EnableWebMvc
public class CORSConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:3333")
                        .allowedOrigins("http://127.0.0.1:3333")
                        .allowedMethods("POST", "GET");
            }
        };
    }

}

 

我将上面的@EnableWebMvc去掉之后就好了,所以这里是跨域问题导致的spring boot 的static content不可访问的问题。

那么@EnableWebMvc,这玩意儿是干嘛的呢?这东西是为了让你的@RestController和@RequestMapping生效的配置,是spring framework提供的功能,而我们的spring boot里根本不需要这玩意儿,所以直接放心的去掉,整个系统就正常了.

 

至于为什么加了这个,就导致mapping 扫描的时候,不可用,这个还有待进一步的研究。

 

 

Spring boot访问js、css、图片(img)访问404无法访问的问题》有3个想法

  1. 其实正确答案就一句话
    @EnableWebMvc (or equivalent) in your app. That would switch off the default Boot MVC config. – Dave Syer Jul 11 ’14 at 19:10

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注