目录

  • 1.解决过程
  • (1)问题描述
  • (2)继承或者实现类不对
  • (3)解决报错402
  • (4)路径写法错误导致的错误
  • 2.总结
  • 3.拓展


1.解决过程

(1)问题描述

参考了网上很多代码,但是放到自己的项目中根本没有用,我在addResourceHandlers()这个方法里面随便打印一个字符串(最原始的调试方法),发现这个方法根本就没有执行。当时我的配置文件继承是这样的:

@Configuration
public class MyWebAppConfiguration implements WebMvcConfigurer {}

也就是说我的配置文件继承的是实现WebMvcConfigurer

(2)继承或者实现类不对

又去找了其他人的教程,发现有的是实现WebMvcConfigurer,有的是继承WebMvcConfigurationSupport,好像还有其他的。
后来我发现我的项目中在其他地方有继承WebMvcConfigurationSupport的配置文件,心想是不是因此才导致我配置的虚拟路径的那个不生效。
于是我把配置的虚拟路径的那个配置文件删掉,直接在最开始的项目中的那个文件中重写addResourceHandlers()方法,还是在这个方法里面随便打印一个字符串,这次这个方法生效了。但是访问图片依然不行,报错402。

// 配置虚拟路径
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    System.out.println("enter-----");
    registry.addResourceHandler("/materials/**").addResourceLocations("file:G:/image/materialImages/");
    registry.addResourceHandler("/scoreapps/**").addResourceLocations("file:G:/image/scoreImages/");
    super.addResourceHandlers(registry);
}

(3)解决报错402

再研究我的配置文件,发现在addResourceHandlers()方法之前还有一个addInterceptors()方法,我猜是我配置的虚拟路径被拦截的,于是在其中的拦截排除配置中加上我配置的虚拟路径,发现还是不行。

//请求拦截
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 先拦截所有请求
        registry.addInterceptor(getAuthenticationInterceptor())
                .addPathPatterns("/**")
                //对登陆页面和静态资源进行放行
                .excludePathPatterns(
                        "/checkLogin","/materials","/scoreapps"
                );
    }

(4)路径写法错误导致的错误

仔细看代码,觉得可能是/materials写法不对,于是改为/materials/**,最终成功。

//请求拦截
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 先拦截所有请求
        registry.addInterceptor(getAuthenticationInterceptor())
                .addPathPatterns("/**")
                //对登陆页面和静态资源进行放行
                .excludePathPatterns(
                        "/checkLogin","/materials/**","/scoreapps"
                );
    }

2.总结

  1. 判断自己的配置文件是否继承或者实现了正确的类
  2. 如果其他地方配置了,看看是否可能存在冲突的情况什么的(我也不懂)
  3. 如果配置了请求拦截,要把配置的虚拟路径放行
  4. 注意方法的路径的写法
  5. 放上整个配置文件
package club.hue.config;

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.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

//必须添加@Configuration注解
@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {

    //请求拦截
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 先拦截所有请求
        registry.addInterceptor(getAuthenticationInterceptor())
                .addPathPatterns("/**")
                //对登陆页面和静态资源进行放行
                .excludePathPatterns(
                        "/checkLogin","/materials/**","/scoreapps"
                );
    }

    // 配置虚拟路径
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/materials/**").addResourceLocations("file:G:/image/materialImages/");
        registry.addResourceHandler("/scoreapps/**").addResourceLocations("file:G:/image/scoreapps/");
        super.addResourceHandlers(registry);
    }
}

3.拓展

  1. 最常见的就是虚拟路径后面没有加发斜杠
  2. 可以加多条,写法如图2那样
  3. 如果是部署到服务器上面,使用nginx的反向代理功能也能实现类似的效果,教程还是蛮多的,实在找不到可以戳我,我配置过,可以提供一些参考
  4. 如果你前端用的vue,并且是提前配置了路径,直接在需要的时候用$imgurl+"picname.png"这样的方式的话,主要在配置$imgurl的时候要把路径写全,即:
//记住加上http://,不然很可能报错
Vue.prototype.$imgurl = "http://localhost:8003/materials"