springboot项目中javaweb上传了图片或文件,但是图片文件无法访问,出现404页面,甚至出现报错

这篇真的是笔者花了两个小时总结的经验,都快想吐槽谁写的史山代码 [其实一年前自己写的],今天就奇了怪了,因为我想在不同环境或者主机的时候不用手动重写自己的绝对映射路径也能正常运行静态资源访问的操作。 但是但是!springboot项目中上传了图片,但是图片无法访问,出现404页面,甚至出现报错。

如果你静态资源映射配置这部分正确,图片文件读写也正确,那你就要考虑组合的问题了,这里不考虑图片文件读写的路径错误,统一用/static/face_img/加文件名的字符串

这是以前敲的:

静态资源映射配置(系统文件绝对路径):

java 复制代码
//静态资源static映射
@Configuration
public class FileUploadConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/face_img/**")
                .addResourceLocations("file:C:\\Users\\ASUS\\Desktop\\中间省略\\static\\face_img\\");
    }

}

文件读写操作:

java 复制代码
  String filename = file.getOriginalFilename();
  String mysqlfilename = "/static/face_img/" + filename;
  // 存放上传图片的文件夹
  File fileDir = ATimelineController.UploadUtils.getImgDirFile();
  // 输出文件夹绝对路径
  try {
  System.out.println(fileDir.getAbsolutePath() + File.separator + filename);
  // 构建真实的文件路径
  File newFile = new File(fileDir.getAbsolutePath() + File.separator + filename);
  System.out.println(newFile);
  // 上传图片到绝对路径
  file.transferTo(newFile);
   } catch (IOException e) {
          e.printStackTrace();
   }


//构建上传图片的文件夹
static class UploadUtils{
// 项目根路径下的目录  -- SpringBoot static 目录相当于是根路径下(SpringBoot 默认)
public final static String IMG_PATH_PREFIX = "static/face_img";

public static File getImgDirFile(){

   // 构建上传文件的存放 "文件夹" 路径
      String fileDirPath = new String("src/main/resources/" + IMG_PATH_PREFIX);
       File fileDir = new File(fileDirPath);
        if(!fileDir.exists()){
                // 递归生成文件夹
                fileDir.mkdirs();
         }
            return fileDir;
      }
}

而我想把静态资源配置改成classpath这种方式,这时候就来聊一下这两个的区别

相同的点: 都是用了WebMvcConfigurer配置
不同的点:

区别在于资源的存储位置。

第一个配置方式使用了文件系统的绝对路径作为资源的存储位置:

.addResourceLocations("file:C:\\Users\\ASUS\\Desktop\\这里中间省略\\static\\face_img\\")

这意味着你的图片实际上是存储在你的本地文件系统中的特定路径下。这种方式的好处是你可以直接在文件系统中管理这些资源,但是缺点是如果你的应用部署到其他环境中,可能会导致资源路径失效或者不可访问。

第二个配置方式使用了classpath作为资源的存储位置:

.addResourceLocations("classpath:/static/face_img/")

这意味着你的图片资源被打包到了你的应用的classpath中。这种方式的好处是你的应用可以在不同环境中移植而不用担心资源路径的问题,但是缺点是你不能直接在文件系统中管理这些资源,需要通过重新打包应用来更新资源。

我想让我的应用可以在不同环境中移植而不用担心资源路径的问题,所以想改成第二种配置方式。

但是,文件读写也要同步改,因为原先写入的图片路径是源代码的静态资源路径,不是打包后的静态资源路径,而第二种配置方式是匹配的打包后的静态资源路径,这时候你上传图片就不能访问正常访问路径。

所以,你应该两个同时改,同时操作的是打包后的静态资源文件。

更新后的:

静态资源映射配置:

java 复制代码
//静态资源映射
@Configuration
public class FileUploadConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/face_img/**")
                .addResourceLocations("classpath:/static/face_img/");
    }
}

文件读写操作:

java 复制代码
  // 拿到文件名
   String filename = System.currentTimeMillis() + "_" + file.getOriginalFilename();

  // 存放上传图片的文件夹
   File fileDir = UploadUtils.getImgDirFile();
 // 输出文件夹绝对路径  -- 这里的绝对路径是相当于当前项目的路径而不是"容器"路径
   //  System.out.println(fileDir.getAbsolutePath());

  try {
       System.out.println(fileDir.getAbsolutePath());
       System.out.println(File.separator);
       System.out.println(fileDir.getAbsolutePath() + File.separator + filename);
    // 构建真实的文件路径
       File newFile = new File(fileDir.getAbsolutePath() + File.separator + filename);
       System.out.println(newFile);
    // 上传图片到 -》 "绝对路径"
       file.transferTo(newFile);
       msg = "上传成功!";

        return "/static/face_img/"+filename;
       } catch (IOException  e) {
        e.printStackTrace();
      }

重要是这个

复制代码
//            String fileDirPath = new String("src/main/resources/" + IMG_PATH_PREFIX);
//            File fileDir = new File(fileDirPath);

要改成

复制代码
ClassPathResource classPathResource = new ClassPathResource(IMG_PATH_PREFIX);File fileDir = null;
fileDir = classPathResource.getFile();
java 复制代码
public class UploadUtils {
    // 项目根路径下的目录  -- SpringBoot static 目录相当于是根路径下(SpringBoot 默认)
      public final static String IMG_PATH_PREFIX = "static/face_img";

      public static File getImgDirFile(){

    // 构建上传文件的存放 "文件夹" 路径
//     String fileDirPath = new String("src/main/resources/" + IMG_PATH_PREFIX);
//     File fileDir = new File(fileDirPath);
      // 获取类路径下的资源
      ClassPathResource classPathResource = new ClassPathResource(IMG_PATH_PREFIX);
       // 获取资源文件夹路径
        File fileDir = null;
     try {
      fileDir = classPathResource.getFile();
 if (!fileDir.exists()) {
       // 递归生成文件夹
          fileDir.mkdirs();
        }
      } catch (IOException e) {
           // 处理异常
                e.printStackTrace();
      }
            return fileDir;
     }

}
相关推荐
CT随2 分钟前
Redis内存碎片详解
java·开发语言
brrdg_sefg11 分钟前
gitlab代码推送
java
hanbarger34 分钟前
mybatis框架——缓存,分页
java·spring·mybatis
cdut_suye42 分钟前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
苹果醋31 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
azhou的代码园1 小时前
基于JAVA+SpringBoot+Vue的制造装备物联及生产管理ERP系统
java·spring boot·制造
wm10432 小时前
java web springboot
java·spring boot·后端
smile-yan2 小时前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风2 小时前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java