SpringBoot项目上传图片(本地/OSS)

SpringBoot项目图片上传

图片上传到本地

可参考视频:

【springboot上传图片的两种方式详解(本地/OSS对象存储)】 https://www.bilibili.com/video/BV1TK411Z7ad/?share_source=copy_web&vd_source=7f0416c71bcbaf44e08ad58367e3f198

视频前十分钟是从0开始编写图片保存到本地,可以照着视频敲出来,不想看也可以直接复制我下面的代码

  • Resources目录下有一个upload.html文件,和一个static文件夹,static下又有一个images文件夹,如下图

    在这里插入图片描述

upload.html

  • upload.html

    这里主要就是一个form表单,用来提交数据,但是要注意的是我这个表单用了postenctype=“multipart/form-data”,以及input的类型是file

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传图片</title>
    </head>
    <body>
    <form action="/uplaod" method="post" enctype="multipart/form-data">
        <input type="file" name="file" value="请选择你要上传的图片">
        <input type="submit" value="上传">
    </form>
    </body>
    </html>
    

controller

  • UploadController

    想直接看源码的同学可以跳过分析,往下滑

    为了方便演示,我把业务都放在controller,,首先我们要先分析文件上传有几步

    1. 文件校验(包括但不限于,图片的大小、图片的类型、图片是否为空、上传的是否是文件等)

      • 我这里只做了一个判空的校验,可以自己加需要的校验
      if (file.isEmpty()) {
              
              
          return "图片上传失败";
      }
      
    2. 将图片重命名,图片重命名又可分为以下几步

      • 获取原来文件的后缀名,可以使用file.getOriginalFilename()获取原来的文件名

        String originalFilename = file.getOriginalFilename(); //原来的图片名
        
      • 生成一个随机的新文件名,这里可以使用UUID.randomUUID()

        String uuid = UUID.randomUUID().toString().replace("-", "");
        
      • 把新名称和原后缀名拼接起来作为新的文件名

        String fileName = uuid + ext;
        
    3. 把图片上传的指定的目录下,我们这里讲的是Resources,就以Resources为例

      • new ApplicationHome(this.getClass())可以获取当前程序运行的路径

        ApplicationHome applicationHome = new ApplicationHome(this.getClass());
        
      • 我们知道Java程序都是运行的.class字节码文件,所以getDir()获取文件夹位置其实是.class字节码文件的位置,需要使用getParentFile()两次回到项目的主程序目录

        applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath()
        
      • 获取到主目录的绝对路径拼接上从这里到Resources下的images

        String pre = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() +
                "\\src\\main\\resources\\static\\images\\";
        
      • 最后通过file.transferTo(new File(path));把文件上传到Resources下的images目录,并且返回一个url地址

        String path = pre + fileName;
        

    完整controller代码:

    @RestController
    public class UploadController {
          
          
    
        @PostMapping("/uplaod")
        public String upload(MultipartFile file) {
          
          
            //图片校验(图片是否为空,图片大小,上传的是不是图片、图片类型(例如只能上传png)等等)
            if (file.isEmpty()) {
          
          
                return "图片上传失败";
            }
            //可以自己加一点校验 例如上传的是不是图片或者上传的文件是不是png格式等等 这里省略
            //获取原来的文件名和后缀
            String originalFilename = file.getOriginalFilename();
    //        String ext = "." + FilenameUtils.getExtension(orgFileName); --需要导依赖
            String ext = "."+ originalFilename.split("\\.")[1];
            //生成一个新的文件名(以防有重复的名字存在导致被覆盖)
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String newName = uuid + ext;
            //拼接图片上传的路径 url+图片名
            ApplicationHome applicationHome = new ApplicationHome(this.getClass());
            String pre = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() + "\\src\\main\\resources\\static\\images\\";
            String path = pre + newName;
            try {
          
          
                file.transferTo(new File(path));
            } catch (IOException e) {
          
          
                e.printStackTrace();
            }
            return path;
        }
    }
    

注意:

这里截取后缀名我为了代码简洁,直接链式调用获取[1]索引位置的后缀,但是这样不太好,可以获取分割出来的字符串数组的最后一个元素

运行

  • 启动Spring Boot项目

  • 访问 http://localhost:8080/upload.html 路径,在浏览器打开upload.html

    在这里插入图片描述

  • 选择上传的图片,点击上传

  • 上传成功后,浏览器返回保存后的绝对路径(这里我为了容易看懂返回的是绝对路径,一般项目中用到的其实是相对路径),如果图片上传失败,浏览器会显示图片上传失败的提示信息

    在这里插入图片描述

  • 图片上传完成之后,我们可以到项目中的==/images==目录下查看,如果图片存在就说明我们已经成功的将图片上传到我们的项目中了

    在这里插入图片描述

  • 同样,我们可以到浏览器访问这张图片

    在这里插入图片描述

  • 一般项目中其实并不会到这一步就结束,而是将这个图片的路径保存到数据库,但是我这里就不继续往下演示了

将图片上传到本地的功能也实现了,有需要的同学可以继续往下看OSS对象存储

OSS对象存储

在这里插入图片描述
在分布式项目中,通常一个项目中会用到很多服务器,如果我们还像单体项目中将文件/图片上传到本地,而下一次访问的时候,如果我们访问的服务器不是上一次保存的服务器的话,我们就访问不到自己上传的数据,这显然不是我们希望的,这时候我们就用到OSS对象存储

  1. 首先你需要一个阿里云OSS对象存储

    创建Bucket

    • 名称:随便起
    • 地域:想你的服务器在哪就选哪个(也是随便选)
    • 存储类型:标准存储
    • 冗余存储:关闭
    • 版本控制:关闭
    • 读写权限:公共读写

    在这里插入图片描述

    具体流程可以参考视频:

    【springboot上传图片的两种方式详解(本地/OSS对象存储)】 https://www.bilibili.com/video/BV1TK411Z7ad/?share_source=copy_web&vd_source=7f0416c71bcbaf44e08ad58367e3f198

    这个视频从11分钟开始讲的是OSS对象存储,照着视频做一样可以实现,另外本篇博客也是基于该视频

  2. 代码

    • 导入依赖

      <dependency>
          <groupId>com.aliyun.oss</groupId>
          <artifactId>aliyun-sdk-oss</artifactId>
          <version>3.15.0</version>
      </dependency>
      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.4</version>
      </dependency>
      <dependency>
          <groupId>commons-beanutils</groupId>
          <artifactId>commons-beanutils</artifactId>
          <version>1.9.3</version>
      </dependency>
      
    • 新建一个工具类UploadUtil在util包下

      1. 需要到阿里云官网获取几个参数

        • 阿里域名(开头加https://,结尾加/,这个不能漏)

        • 地域节点(开头加http://,一样不能少)

          在这里插入图片描述

        • accessKeyId

        • accessKeySecret

          在这里插入图片描述

      2. 生成一个新的文件名

      3. 使用OSS客户端对象上传图片返回url

      UploadUtil

      public class UploadUtil {
              
              
          //域名(开头需要https://,结尾要/)
          public static final String ALI_DOMAIN = "https://你的阿里云域名/";
      
          public static String uploadImg(MultipartFile file) throws Exception {
              
              
              //生成的文件名
              String uuid = UUID.randomUUID().toString().replace("-", "");
              String originalFilename = file.getOriginalFilename();
              String ext = "." + FilenameUtils.getExtension(originalFilename);
              String fileName = uuid + ext;
              //地域节点(开头需要http://)
              String endpoint = "你的地域节点";
              String accessKeyId = "你的accessKeyId";
              String accessKeySecret = "你的accessKeySecret";
              //OSS客户端对象
              OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
              ossClient.putObject(
                      "你的仓库名", //仓库名
                      fileName, //文件名
                      file.getInputStream()
                      );
              ossClient.shutdown();
              return ALI_DOMAIN + fileName;
          }
      }
      

      controller

      @PostMapping("/upImg")
      public String upImg(MultipartFile file) throws IOException {
              
              
          return UploadUtil.uploadImage(file);
      }
      

      upload.html

      <form action="/upImg" method="post" enctype="multipart/form-data">
          <input type="file" name="file" value="上传图片">
          <input type="submit" value="上传">
      </form>
      
    • 测试方法和本地运行一致

    • 上传成功后可以讲路径复制到浏览器访问,也可以打开阿里云官网OSS对象存储查看上传的图片

    在这里插入图片描述

可能会遇到的问题

如何搭建spring boot项目

搭建一个spring boot项目

  • pom.xml导入web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 编写启动类
@SpringBootApplication
public class Run {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(Run.class, args);
    }
}

如何使用Postman测试文件上传

如果要使用postman测试,可以不用写html页面

Params上加上Content-Type=multipart/form-data,Body中选择form-data
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aichijvzi/article/details/128344310
今日推荐