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

05-01 4345阅读 0评论

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

 

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

这是以前敲的:

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

//静态资源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\");
    }
}

文件读写操作:

  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中。这种方式的好处是你的应用可以在不同环境中移植而不用担心资源路径的问题,但是缺点是你不能直接在文件系统中管理这些资源,需要通过重新打包应用来更新资源。

 

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

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

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

更新后的:

静态资源映射配置:

//静态资源映射
@Configuration
public class FileUploadConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/face_img/**")
                .addResourceLocations("classpath:/static/face_img/");
    }
}

文件读写操作:

  // 拿到文件名
   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();
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;
     }
}

免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,4345人围观)

还没有评论,来说两句吧...

目录[+]