阿里云oss文件上传工具类

简介

  • 文件上传,也称为upload,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。

  • 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。

 前端代码

<form action="#" method="post" enctype="multipart/form-data">
    姓名: <input type="text" name="name"/><br/>
    年龄: <input type="text" name="age"/></br>
    图片: <input type="file" name="image"/><br/><br/>
    <input type="submit" value="提交"/>
</form>

上传文件的原始form表单,要求表单必须具备以下三点(上传文件页面三要素):

  • 表单必须有 file 域,用于选择要上传的文件。

  • 表单提交方式必须为 POST

  • 表单的编码类型enctype必须要设置为 multipart/form-data

如果我们加上 enctype="multipart/form-data",代表的是我们请求的数据是多部分的,通过浏览器的开发者工具( firefox浏览器 ),我们也可以看到请求的数据:

后端代码

在服务端,我们要想接收上传上来的文件,需要使用Spring给我们提供的一个,专门接收文件的API : MultipartFile。

import com.itheima.pojo.Result;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@RestController
public class UploadController {

    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        System.out.println(image.getName)
        return Result.success();
    }
	
}

上传上来的文件,其实呢,是暂存在系统的临时文件中了。 我们可以通过debug,就可以看出来。

本地存储

对于这个图片上传功能呢,主要分为两部操作:

  • 选择文件,进行图片上传,将图片文件上传到服务器存储起来,然后返回图片访问的URL。

  • 当点击保存时,除了页面的基本表单数据需要提交到服务端,图片访问的URL,也需要提交到服务端。

代码实现

我们先来完成第一部分,将上传的图片保存在本地磁盘目录。

package com.itheima.controller;

import com.itheima.pojo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
public class UploadController {

    @Autowired
    private AliOSSUtils aliOSSUtils;

    //上传至本地服务器
    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        //获取原始文件名
        String originalFilename = image.getOriginalFilename();
        //构建新的文件名
        String newFileName = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
        //将文件保存在服务器端 E:/images/ 目录下
        image.transferTo(new File("E:/images/"+newFileName));
        return Result.success();
    }
    
}

MultipartFile 常见方法:

getOriginalFilename():获取原始文件名 ​

getContentType():获取文件的类型 ​

getInputStream():获取文件的输入流 ​

getBytes():获取文件的字节数组

测试

可以直接使用我们准备好的文件上传的页面进行测试。

配置

在我们进行图片上传的测试中,我们发现,有时候可以上传成功,而有时候呢,又不能上传成功,报出如下错误。

 报错我原因呢,是因为:在SpringBoot中,文件上传,默认单个文件允许最大大小为 1M,如果需要上传大文件,可以在application.properties进行如下配置:

#配置单个文件的最大上传大小
spring.servlet.multipart.max-file-size=10MB

#配置单个请求最大上传大小(一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB

阿里云OSS

介绍

阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供99.9999999999% (12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。

步骤

 注册完账号之后,就可以登录阿里云:

 点击控制台,然后找到 对象存储OSS 服务。

 如果是第一次访问,还需要开通 对象存储服务OSS。

 开通之后,就可以进入到阿里云对象存储的控制台。

 点击左侧的 "Bucket列表",然后创建一个Bucket。

文件上传

参照官方提供的SDK,改造一下,即可实现文件上传功能。

1). pom.xml

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.15.0</version>
</dependency>

2). 测试文件上传

import org.junit.jupiter.api.Test;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import java.io.FileInputStream;
import java.io.InputStream;

public class AliOssTest {

    @Test
    public void testOss(){
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "********";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "********";
        String accessKeySecret = "*********";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "web-397";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "0001.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath= "C:\\Users\\Administrator\\Pictures\\Saved Pictures\\10.jpg";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Exception ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

在上述的代码中,需要替换的内容为:

  • accessKeyId:阿里云账号AccessKey

  • accessKeySecret:阿里云账号AccessKey对应的秘钥

  • bucketName:Bucket名称

  • objectName:对象名称,在Bucket中存储的对象的名称

  • filePath:文件路径

案例集成OSS

引入阿里云OSS文件上传工具类(由官方SDK改造而来

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 阿里云 OSS 工具类
 */
@Component
public class AliOSSUtils {
    
    private String endpoint = "*************";
    private String accessKeyId = "*************";
    private String accessKeySecret = "*************";
    private String bucketName = "web-397";
	
    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile multipartFile) throws IOException {
        // 获取上传的文件的输入流
        InputStream inputStream = multipartFile.getInputStream();
		
        // 避免文件覆盖
        String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + multipartFile.getOriginalFilename();
		
        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);
		
        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        
        // 关闭ossClient
        ossClient.shutdown();
        return url;// 把上传到oss的路径返回
    }

}

上传图片功能升级改造

在原有的UploadController的基础上进行升级改造

@RestController
public class UploadController {
	
    @Autowired
    private AliOSSUtils aliOSSUtils;
	
    //上传至本地服务器
    /*@PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        //获取原始文件名
        String originalFilename = image.getOriginalFilename();
        //构建新的文件名
        String newFileName = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
        //将文件保存在服务器端 E:/images/ 目录下
        image.transferTo(new File("E:/images/"+newFileName));
        return Result.success();
    }*/
	
    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        String url = aliOSSUtils.upload(image);
        return Result.success(url);
    }
	
}

测试

猜你喜欢

转载自blog.csdn.net/anyi2351033836/article/details/130420227