当前位置: 首页 > news >正文

OSS文件上传(一):简单上传

        在现代 Web 应用中,文件上传是核心功能之一,而当面对大文件(如视频、压缩包等)时,传统的单文件上传方案往往会遇到超时、网络波动失败、效率低下等问题。阿里云 OSS(Object Storage Service)作为稳定可靠的对象存储服务,提供了完善的文件上传解决方案。本文将从基础的简单上传讲起,逐步深入到分片上传,并结合 Redis 实现断点续传功能,深入剖析OSS文件上传功能,帮助你构建高效、稳定的大文件上传系统。

OSS 文件上传基础:简单上传

        简单上传适用于小文件场景(通常建议文件大小≤100MB),通过 OSS 的PutObject接口直接将文件上传到 OSS。这种方式实现简单,适合快速集成。

        

1. 环境准备

(1)依赖配置(Maven)

首先在pom.xml中添加 OSS SDK 相关依赖:

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

如果使用的是Java 9及以上的版本,则需要添加以下JAXB相关依赖:

<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version>
</dependency>
<dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version>
</dependency>

(2)OSS 配置

application.yml中配置 OSS 连接信息:

aliyun:oss:endpoint: oss-cn-beijing.aliyuncs.com # 地域Endpointaccess-key-id: your-access-key-idaccess-key-secret: your-access-key-secretbucket-name: your-bucket-name # 存储桶名称

创建配置类初始化 OSS 客户端:

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "aliyun")
public class AliYunConfig {private String accessKey; // 阿里云AccessKeyIdprivate String accessKeySecret; // 阿里云AccessKeySecretprivate String ossBucket; // 存储桶名称private String ossEndpoint; // OSS地域节点@Beanpublic OSS oSSClient() {return new OSSClient(ossEndpoint, accessKey, accessKeySecret);}
}

创建统一结果返回类:

package com.netflow.utils;import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;/*** 统一结果返回类* @param <T> 返回数据的类型*/public class Msg<T> implements Serializable {private static final long serialVersionUID = 1L;// 状态码private int code;// 消息private String message;// 返回数据private T data;// 时间戳private long timestamp;// 附加数据(可选)private Map<String, Object> extra;// 构造方法private Msg() {this.timestamp = System.currentTimeMillis();}private Msg(int code, String message) {this();this.code = code;this.message = message;}private Msg(int code, String message, T data) {this(code, message);this.data = data;}// 成功静态工厂方法public static <T> Msg<T> success() {return new Msg<>(200, "操作成功");}public static <T> Msg<T> success(String message) {return new Msg<>(200, message);}public static <T> Msg<T> success(T data) {return new Msg<>(200, "操作成功", data);}public static <T> Msg<T> success(String message, T data) {return new Msg<>(200, message, data);}// 失败静态工厂方法public static <T> Msg<T> fail() {return new Msg<>(500, "操作失败");}public static <T> Msg<T> fail(String message) {return new Msg<>(500, message);}public static <T> Msg<T> fail(int code, String message) {return new Msg<>(code, message);}// 链式调用方法public Msg<T> code(int code) {this.code = code;return this;}public Msg<T> message(String message) {this.message = message;return this;}public Msg<T> data(T data) {this.data = data;return this;}public Msg<T> extra(String key, Object value) {if (this.extra == null) {this.extra = new HashMap<>();}this.extra.put(key, value);return this;}// Getter方法public int getCode() {return code;}public String getMessage() {return message;}public T getData() {return data;}public long getTimestamp() {return timestamp;}public Map<String, Object> getExtra() {return extra;}@Overridepublic String toString() {return "Msg{" +"code=" + code +", message='" + message + '\'' +", data=" + data +", timestamp=" + timestamp +", extra=" + extra +'}';}
}

2. 简单上传实现

简单上传的核心是通过 OSS 客户端的putObject方法直接上传文件流,代码如下:

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.netflow.config.AliYunConfig;
import com.netflow.utils.Msg;
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.RequestParam;
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
@Slf4j
public class OSScontroller {@AutowiredOSS ossClient;@AutowiredAliYunConfig aliYunConfig;@PostMapping("/upload")public Msg<String> uploadFile(@RequestParam("file") MultipartFile file) {try {//获取初始文件名String fileName = file.getOriginalFilename();//获取文件后缀String suffixName = fileName.substring(fileName.lastIndexOf("."));//UUID作为文件名String newFileName = UUID.randomUUID().toString()+ "-"+ fileName + suffixName;// 创建PutObjectRequest对象。PutObjectRequest putObjectRequest = new PutObjectRequest(aliYunConfig.getOssBucket(), newFileName, file.getInputStream());// 上传文件。PutObjectResult result = ossClient.putObject(putObjectRequest);return Msg.success("上传成功");} 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 | IOException 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();}}return Msg.fail("上传失败");}}

3. 简单上传的局限性

简单上传虽然实现简单,但存在明显短板:

  • 文件大小限制:单次上传最大支持 5GB(OSS 限制),但实际网络中 1GB 以上文件易失败;
  • 无断点续传:网络中断后需重新上传整个文件;
  • 效率低:单线程上传,无法利用带宽资源。

因此,对于大文件(建议>100MB),需采用分片上传方案。想要了解分片上传内容的小伙伴可以参考我的另一篇文章

OSS文件上传(二):分片上传-CSDN博客

http://www.dtcms.com/a/288650.html

相关文章:

  • feignClient 调用详细流程
  • Valgrind Memcheck 全解析教程:6个程序说明基础内存错误
  • 判断一个数是否为质数方法
  • VSCode使用Jupyter完整指南配置机器学习环境
  • c#:TCP服务端管理类
  • 正点原子stm32F407学习笔记10——输入捕获实验
  • 2025 年科技革命时刻表:四大关键节点将如何重塑未来?
  • 内网后渗透攻击过程(实验环境)--3、横向攻击
  • SQL 调优第一步:EXPLAIN 关键字全解析
  • 【已解决】GitHub SSH 连接失败解决方案:Permission Denied (publickey) 错误修复指南
  • [Linux]进程 / PID
  • 30天打牢数模基础-决策树讲解
  • Linux入门篇学习——NFS 服务器的搭建和使用和开发板固件烧录
  • Spring Boot 第一天知识汇总
  • 【Java项目安全基石】登录认证实战:Session/Token/JWT用户校验机制深度解析
  • 相似度计算
  • 「Java案例」利用方法求反素数
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 饱和预测 Saturating Forecasts
  • dynamic_cast的实现原理
  • Beamer-LaTeX学习(教程批注版)【6】
  • Elasticsearch 简化指南:GCP Google Compute Engine
  • GPT-4o mini TTS:领先的文本转语音技术
  • 随着GPT-5测试中泄露OpenAI 预计将很快发布 揭秘GPT-5冲击波:OpenAI如何颠覆AI战场,碾压谷歌和Claude?
  • prometheus 黑盒监控和docker检测
  • mysql第三次作业
  • 学习寄存器——GPIO(二)学习BSRR BRR ODR寄存器的原子性和在HAL库的应用
  • 【Go语言-Day 22】解耦与多态的基石:深入理解 Go 接口 (Interface) 的核心概念
  • 【详细笔记】两类曲线积分转换
  • 群组功能实现指南:从数据库设计到前后端交互,上班第二周
  • 【数据结构】揭秘二叉树与堆--用C语言实现堆