文件上传和存储(阿里云OSS)

Author:Dawn_T17🥥 

目录

文件上传 

存在本地 

MultipartFile

UUID

存在云端

阿里云OSS

Bucket 

SDK参考文档

Java SDK 安装

Java简单上传

配置密钥ID和SECRET的环境变量

 OSS上传图像案例演示

阿里云OSS集成 



文件上传 

在 HTML 表单中,enctype(编码类型)属性用于指定表单数据在发送到服务器时的编码方式。主要有以下几种常见的值:

  1. application/x-www-form-urlencoded这是默认的编码类型。表单数据被编码为键值对的形式,例如key1=value1&key2=value2。适用于大多数常规的表单提交情况。
  2. multipart/form-data:当表单中包含文件上传字段时,通常使用这个编码类型。它允许同时传输文本数据和文件数据。
  3. text/plain:以纯文本的形式编码表单数据,不太常用。

若文件上传时候,用默认编码格式,则只会上传文件的名字

存在本地 

案例: 

@Slf4j
@RestController
public class UploadController {
    @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image){
        log.info("文件上传:{},{},{}",username,age,image);
        return Result.success();
    }
}

1.路径参数和前端设置的要一样

2.用MultipartFile存储文件

MultipartFile

是 Spring 框架中用于处理文件上传的接口。

一、主要用途

  1. 文件上传:在 Spring MVC 应用中,当客户端通过表单提交文件时,服务器端可以使用MultipartFile来接收和处理上传的文件。例如,在控制器方法中,可以将一个MultipartFile类型的参数作为上传文件的接收对象。
  2. 文件操作:提供了一系列方法来获取文件的信息和进行文件操作。比如,可以获取文件的原始名称、大小、内容类型等信息,还可以将文件内容读取为字节数组或输入流。

二、常见方法

  1. getOriginalFilename():返回上传文件的原始文件名。
  2. getSize():返回文件的大小(以字节为单位)。
  3. getContentType():获取文件的内容类型。
  4. getBytes():将文件内容读取为字节数组。
  5. getInputStream():获取文件的输入流,可用于进一步处理文件内容。

三、使用示例

以下是一个简单的 Spring MVC 控制器方法示例,用于处理文件上传:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                // 可以对文件内容进行进一步处理
                return "文件上传成功!文件名:" + file.getOriginalFilename();
            } catch (Exception e) {
                return "文件上传失败:" + e.getMessage();
            }
        } else {
            return "请选择要上传的文件!";
        }
    }
}

文件转存 :

@Slf4j
@RestController
public class UploadController {
    @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image) throws IOException {
        log.info("文件上传:{},{},{}",username,age,image);
        //将文件转存在服务器的磁盘目录中C:\Users\thl32\Desktop\JavaWeb\TrainingCase\image
        String originalFilename = image.getOriginalFilename();//获取原始文件名
        System.out.println(originalFilename);
        image.transferTo(new File("C:\\Users\\thl32\\Desktop\\JavaWeb\\TrainingCase\\image\\"+originalFilename));
        return Result.success();
    }
}

存在问题:

如果都以文件原名存储,当存入两个相同名称的文件时,后一个文件会覆盖前一个文件 

优化:

构造唯一文件名,不能重复--uuid(通用唯一识别码)

UUID

(Universally Unique Identifier),即通用唯一识别码。

一、特点

  1. 唯一性:UUID 可以确保在分布式系统中生成的标识符几乎不会重复,这使得它非常适合用于在不同的系统和组件之间唯一标识对象。
  2. 随机性:通常由随机数生成器生成,具有较高的随机性,难以被猜测。
  3. 长度固定:一般为 36 个字符的字符串表示形式,包括连字符。例如:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,其中每个x代表一个十六进制数字。

二、用途

  1. 数据库主键:在数据库设计中,可以使用 UUID 作为主键,避免传统的自增整数主键可能带来的问题,如在分布式环境下的主键冲突。
  2. 资源标识:用于唯一标识各种资源,如文件、用户、订单等。在分布式系统中,不同的节点可以独立生成 UUID,而不用担心冲突。
  3. 安全领域:在一些安全相关的场景中,UUID 可以用于生成随机的令牌(token),用于身份验证和授权

三、生成方式

在 Java 中,可以使用java.util.UUID类来生成 UUID。例如:

import java.util.UUID;

public class UUIDExample {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println(uuid);
    }
}

案例展示:

substring方法有以下两种形式:

  • substring(int beginIndex):从指定的索引beginIndex开始截取到字符串末尾,返回一个新的字符串。
  • substring(int beginIndex, int endIndex):从beginIndex开始截取到endIndex(不包括endIndex位置的字符),返回一个新的字符串。
@Slf4j
@RestController
public class UploadController {
    @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image) throws IOException {
        log.info("文件上传:{},{},{}",username,age,image);
        //将文件转存在服务器的磁盘目录中C:\Users\thl32\Desktop\JavaWeb\TrainingCase\image
        String originalFilename = image.getOriginalFilename();//获取原始文件名
        //构造唯一文件名,不能重复--uuid(通用唯一识别码)
        //获取文件后缀名——文件类型
        int index = originalFilename.lastIndexOf(".");
        String extname= originalFilename.substring(index);
        String newFileName= UUID.randomUUID().toString()+extname;
        System.out.println(newFileName);

        image.transferTo(new File("C:\\Users\\thl32\\Desktop\\JavaWeb\\TrainingCase\\image\\"+newFileName));
        return Result.success();
    }
}

生成的uuid唯一文件名称 

 

总结:

存在云端

云端存储的优势

  1. 便捷性

    • 无论你身处何地,只要有网络连接,就可以随时随地访问存储在云端的文件。比如,你在出差途中可以使用笔记本电脑、平板电脑或手机轻松查看和编辑云端存储的文档。
    • 无需携带物理存储设备,如 U 盘或移动硬盘,减少了丢失或损坏的风险。
  2. 安全性

    • 云服务提供商通常会采取多种安全措施来保护用户的数据,包括数据加密、备份和访问控制等。
    • 例如,一些云存储服务会对数据进行加密传输和存储,确保即使数据在传输过程中被截获或存储设备被物理窃取,也难以破解其中的内容。同时,通过设置用户权限,可以控制谁能够访问特定的文件,提高数据的安全性。
  3. 可靠性

    • 云存储通常具有高可靠性,云服务提供商一般会在多个数据中心进行数据备份,以防止因硬件故障、自然灾害等原因导致数据丢失。
    • 如果一个数据中心出现问题,云服务提供商可以迅速切换到其他备份数据中心,确保用户数据的可用性。
  4. 可扩展性

    • 随着你的数据量不断增长,云端存储可以很容易地进行扩展,无需担心存储空间不足的问题。
    • 你可以根据自己的需求随时购买更多的存储空间,而不需要更换物理存储设备。

阿里云OSS

阿里云OSS简介


阿里云对象存储服务(Object Storage Service,简称OSS)为您提供基于网络的数据
存取服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频
等在内的各种非结构化数据文件。
阿里云OSS将数据文件以对象(object)的形式上传到存储空间(bucket)中。
您可以进行以下操作:
创建一个或者多个存储空间,向每个存储空间中添加一个或多个文件。
通过获取已上传文件的地址进行文件的分享和下载。
通过修改存储空间或文件的属性或元信息来设置相应的访问权限。
在阿里云管理控制台执行基本和高级OSS任务。
使用阿里云开发工具包或直接在应用程序中进行RESTful API调用执行基本和高级OSS任务

Bucket 

在阿里云对象存储服务(OSS)中,Bucket 即存储空间的意思。

一、主要作用

  1. 存储对象

    • Bucket 是用于存储各种类型文件的容器,你可以将图片、视频、文档等各种数据对象上传到 Bucket 中进行存储。
    • 例如,一个网站的所有图片资源可以存储在一个特定的 Bucket 中,方便管理和访问。
  2. 访问控制

    • 可以对 Bucket 设置不同的访问权限,控制谁可以访问其中的对象以及可以进行哪些操作。
    • 比如,可以设置为公开可读,让所有人都能访问特定 Bucket 中的某些公开资源;也可以设置为私有访问,只有经过授权的用户才能访问。
  3. 数据管理

    • 通过 Bucket 可以对存储的对象进行分类管理,不同类型的数据可以存储在不同的 Bucket 中。
    • 你可以对 Bucket 中的对象进行删除、复制、移动等操作,方便进行数据的整理和维护。

二、与其他概念的关系

  1. 与对象的关系

    • Bucket 中包含了众多的对象。对象是具体的数据文件,而 Bucket 则是容纳这些对象的容器。
    • 就像一个文件夹(Bucket)里面可以存放多个文件(对象)一样。
  2. 与地域的关系

    • Bucket 在创建时需要选择一个地域。不同地域的 Bucket 之间数据是隔离的,选择合适的地域可以提高数据访问的速度和降低网络延迟。
    • 例如,如果你的业务主要在某个特定地区,选择靠近该地区的地域创建 Bucket 可以提高用户访问存储在其中的对象的速度。

注册登录阿里云,购买OSS(0元),创建Bucket,调整配置

SDK参考文档

SDK参考_对象存储(OSS)-阿里云帮助中心 (aliyun.com)

在软件开发中,SDK(Software Development Kit,软件开发工具包)是一组用于特定软件包、软件框架、硬件平台、操作系统等创建应用程序的开发工具的集合。

一、SDK 的组成部分

  1. 库和 API
    • SDK 通常包含一系列的库(libraries)和应用程序编程接口(APIs)。这些库提供了预先编写好的功能模块,开发人员可以直接调用这些模块来实现特定的功能,而无需从头开始编写代码。
    • 例如,一个图形处理 SDK 可能包含用于图像加载、编辑和渲染的库,以及相应的 API,开发人员可以使用这些 API 来轻松地在他们的应用程序中实现图形处理功能。
  2. 文档
    • 好的 SDK 会提供详细的文档,包括 API 参考手册、教程、示例代码等。文档帮助开发人员了解如何使用 SDK 中的各种功能,以及如何解决可能遇到的问题。
    • 比如,一个移动开发 SDK 的文档可能会介绍如何集成该 SDK 到不同的移动操作系统中,如何使用其提供的功能来实现推送通知、地图显示等功能,并提供示例代码供开发人员参考。
  3. 开发工具
    • 一些 SDK 还会提供开发工具,如编译器、调试器、性能分析工具等。这些工具可以帮助开发人员更高效地开发和调试应用程序。
    • 例如,一个游戏开发 SDK 可能会提供一个专门的游戏引擎编辑器,开发人员可以使用这个编辑器来设计游戏场景、创建角色和动画,并进行实时预览和调试。

二、SDK 的作用

提高开发效率

  • 通过提供现成的功能模块和工具,SDK 可以大大减少开发人员的工作量,提高开发效率。开发人员可以专注于实现应用程序的核心业务逻辑,而无需花费大量时间在底层功能的实现上。
  • 例如,使用一个支付 SDK,开发人员可以在很短的时间内为他们的应用程序添加支付功能,而无需自己实现复杂的支付流程和安全机制。

  1. 保证兼容性和稳定性
    • SDK 通常是由专业的开发团队开发和维护的,经过了严格的测试和优化。使用 SDK 可以保证应用程序在不同的平台和环境下具有良好的兼容性和稳定性。
    • 比如,一个移动开发 SDK 会针对不同的移动操作系统和设备进行适配,确保应用程序在各种设备上都能正常运行。
  2. 促进技术创新
    • SDK 可以让开发人员快速集成最新的技术和功能,促进技术创新。开发人员可以利用 SDK 提供的先进功能来提升应用程序的竞争力,满足用户不断变化的需求。
    • 例如,一个人工智能 SDK 可以让开发人员轻松地为他们的应用程序添加语音识别、图像识别等人工智能功能,为用户提供更加智能化的体验。

三、OSS 的 SDK

对于阿里云对象存储服务(OSS),也提供了相应的 SDK。OSS 的 SDK 可以帮助开发人员更方便地与 OSS 进行交互,实现文件上传、下载、删除、管理等操作。

  1. 支持多种编程语言
    • OSS 的 SDK 支持多种编程语言,如 Java、Python、Node.js、C# 等。开发人员可以根据自己的项目需求和技术栈选择合适的编程语言进行开发。
    • 例如,如果你是一个 Java 开发人员,可以使用 OSS 的 Java SDK 来快速集成 OSS 到你的项目中。
  2. 简化开发流程
    • OSS 的 SDK 提供了简洁易用的 API,开发人员可以通过几行代码就实现与 OSS 的交互。同时,SDK 还提供了一些高级功能,如断点续传、分块上传、文件加密等,进一步简化了开发流程。
    • 比如,使用 OSS 的 SDK 进行文件上传时,可以自动处理网络中断等异常情况,实现断点续传,确保文件上传的可靠性。
  3. 提高开发效率和稳定性
    • 与直接使用 OSS 的 API 相比,使用 SDK 可以提高开发效率和稳定性。SDK 对底层的网络通信、数据处理等进行了封装和优化,提供了更好的性能和错误处理机制。
    • 例如,在高并发的场景下,使用 OSS 的 SDK 可以更好地处理大量的文件上传和下载请求,确保系统的稳定性和可靠性。

Java SDK 安装

如果您需要管理OSS存储空间、上传下载文件、管理数据、进行图片处理等,可以先安装Java SDK

在Maven中引入相关依赖(见帮助文档)

Java简单上传

简单上传是指通过PutObject方法上传单个文件(Object)。

简单上传包括流式上传和文件上传,流式上传使用InputStream作为OSS文件的数据源,文件上传使用本地文件作为OSS文件的数据源。

配置密钥ID和SECRET的环境变量

(新版OSS都要求环境变量获取密码)

配置好之后重启电脑

 OSS上传图像案例演示

根据SDK提供的JAVA简单上传中的上传文件流中的代码

直接把样例代码复制到Spring Boot测试目录下

更改自己的需求

启动这个main方法

package com.traingcase;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.FileInputStream;
import java.io.InputStream;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "dawn-web-framework01";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "1.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath= "C:\\Users\\thl32\\Pictures\\Saved Pictures\\头像\\QQ图片20240504164113.png";

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

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } 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 (ClientException 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();
            }
        }
    }
} 

成功运行后,即可在OSS自建的Bucket中看到这个文件 

成功加入Bucket后,OSS会为这个图片生成一个URL

在前端中,在HTML里的image标签里加上这个URL,即可渲染展示出图片 

阿里云OSS集成 

 

获得URL的工具类

根据阿里云OSS官方提供的代码改写而成

自己修改需要的配置

通过字符串拼接,获得文件访问路径

package com.traingcase.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyuncs.exceptions.ClientException;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.UUID;

/**
 * 阿里云 OSS 工具类
 * 根据阿里云OSS官方提供的代码改写
 */

//用Spring环境,就不建议New一个对象,直接交给ioc容器管理
@Component
public class AliOSSUtils {

    private String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
//    private String accessKeyId = "LTAI4GCH1vX6DKqJWxd6nEuW";
//    private String accessKeySecret = "yBshYweHOpqDuhCArrVHwIiBKpyqSL";
    private String bucketName = "dawn-web-framework01";

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException, ClientException {
        // 获取上传的文件的输入流
        InputStream inputStream = file.getInputStream();
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 避免文件覆盖
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        // 关闭ossClient
        ossClient.shutdown();
        return url;// 把上传到oss的路径返回
    }

}

 在Controller中 通过MultipartFile接口,获得文件并调用工具类(👆),实现存到云端,并响应给前端文件的URL

package com.traingcase.controller;

import com.aliyuncs.exceptions.ClientException;
import com.traingcase.pojo.Result;
import com.traingcase.utils.AliOSSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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;


@Slf4j
@RestController
public class UploadController {
    //图片保存在本地
//    @PostMapping("/upload")
//    public Result upload(String username, Integer age, MultipartFile image) throws IOException {
//        log.info("文件上传:{},{},{}",username,age,image);
//        //将文件转存在服务器的磁盘目录中C:\Users\thl32\Desktop\JavaWeb\TrainingCase\image
//        String originalFilename = image.getOriginalFilename();//获取原始文件名
//        //构造唯一文件名,不能重复--uuid(通用唯一识别码)
//        //获取文件后缀名——文件类型
//        int index = originalFilename.lastIndexOf(".");
//        String extname= originalFilename.substring(index);
//        String newFileName= UUID.randomUUID().toString()+extname;
//        System.out.println(newFileName);
//
//        image.transferTo(new File("C:\\Users\\thl32\\Desktop\\JavaWeb\\TrainingCase\\image\\"+newFileName));
//        return Result.success();
//    }

    //图片保存在云端

    //用Spring环境,就不建议New一个对象,直接交给ioc容器管理
    @Autowired
    private AliOSSUtils aliOSSUtils;

    @PostMapping("/upload")
    public Result upload( MultipartFile image) throws IOException, ClientException {
     log.info("文件上传 {}",image.getOriginalFilename());
     //调用阿里云OSS工具类上传文件到云端
        String url=aliOSSUtils.upload(image);
        log.info("文件上传完成,文件访问的url:{}",url);
        return Result.success(url);

    }
}

运行代码,并通过ApiPost请求上传文件

成功获得云端图片的URL 

阿里云OSS(对象存储服务)提供了丰富的API和工具,可以方便地实现文件的上传和下载功能。根据提供的引用内容,以下是基于阿里云OSS实现文件上传和下载的步骤: 1. 配置OSS服务:在阿里云官网上购买OSS服务,并完成相应的配置。\[1\] 2. 创建Controller层:在Controller层中,使用@RestController注解标记类,并使用@PostMapping注解标记上传文件的接口。在接口方法中,使用@ApiOperation注解添加接口的描述信息,使用@ApiImplicitParam注解指定接口参数。\[2\] 3. 实现上传功能:在Service层中,创建实现上传功能的服务类。在该类中,注入OSSUtils工具类,并实现上传文件的方法。在方法中,首先对文件类型进行检查,然后调用工具类的上传文件方法。\[3\] 4. 实现下载功能:类似地,在Service层中创建实现下载功能的服务类。在该类中,注入OSSUtils工具类,并实现下载文件的方法。在方法中,调用工具类的下载文件方法。 需要注意的是,上传和下载文件时,需要使用阿里云OSS提供的SDK或API进行操作。具体的实现步骤可以参考阿里云的文档,其中包括SDK的引入、配置OSS客户端、创建Bucket等详细步骤。 总结起来,基于阿里云OSS实现文件上传和下载的步骤包括:配置OSS服务、创建Controller层、实现上传功能和下载功能,并使用阿里云OSS提供的SDK或API进行操作。 #### 引用[.reference_title] - *1* *2* *3* [在项目中使用阿里云oss实现文件上传功能](https://blog.csdn.net/m0_63445035/article/details/130417961)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值