文档地址
https://help.aliyun.com/zh/oss/object-file-object/
创建存储空间(Bucket)
https://oss.console.aliyun.com/bucket
出于安全考虑,OSS 控制台默认开启阻止公共访问,仅支持创建私有权限的Bucket。
如需改为 公共读 或 公共读写,请按以下步骤操作:
-
单击目标Bucket名称进入该Bucket。
-
在左侧导航栏选择 权限控制 > 阻止公共访问,关闭该策略。
-
切换至 读写权限 页签,单击 设置。
-
按引导修改 Bucket 的读写权限为公共读或公共读写。
引入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>
java代码
@Slf4j public class OssFileUploaderUtil {private static final String accessKeyId = "xxxxxxx";private static final String accessKeySecret = "xxxxxxxxx";// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。private static final String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";private static final String bucketName = "work";// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。private static final String region = "cn-hangzhou";private final boolean isPublicBucket = false; // 是否为公开Bucket(影响下载链接生成方式)/*** 上传字节流到OSS并返回下载链接* @param fileBytes 文件字节数组(如Excel模板的字节流)* @param fileName 文件名(含扩展名,如:用户模板_20250910.xlsx)* @param fileDir OSS存储目录(如:user/templates/,末尾需带斜杠)* @param contentType 文件MIME类型(如:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)* @return 可直接访问的下载链接* @throws IOException 流处理异常*/public static String upload(byte[] fileBytes, String fileName, String fileDir, String contentType) throws IOException {// 1. 构建OSS文件完整路径(目录+文件名)String objectPath = fileDir + fileName;log.info("开始上传文件到OSS,路径:{}", objectPath);OSS ossClient = null;ByteArrayInputStream inputStream = null;try {// 2. 初始化OSS客户端DefaultCredentialProvider credentialProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);ClientBuilderConfiguration clientConfig = new ClientBuilderConfiguration();clientConfig.setSignatureVersion(SignVersion.V4); // 使用V4签名算法ossClient = OSSClientBuilder.create().endpoint(endpoint).credentialsProvider(credentialProvider).clientConfiguration(clientConfig).region(region).build();// 3. 配置文件元数据ObjectMetadata metadata = new ObjectMetadata();metadata.setContentType(contentType); // 关键:指定文件类型,避免下载异常metadata.setContentLength(fileBytes.length); // 设置文件大小metadata.setContentEncoding("UTF-8");// 4. 上传文件流inputStream = new ByteArrayInputStream(fileBytes);PutObjectRequest putRequest = new PutObjectRequest(bucketName, objectPath, inputStream, metadata);ossClient.putObject(putRequest);log.info("文件上传OSS成功,路径:{}", objectPath);// 5. 生成下载链接return generateDownloadUrl(objectPath);} catch (OSSException e) {log.error("OSS上传失败!错误码:{},请求ID:{}", e.getErrorCode(), e.getRequestId(), e);throw new RuntimeException("文件上传OSS失败:" + e.getMessage(), e);} finally {// 6. 释放资源if (inputStream != null) {inputStream.close();}if (ossClient != null) {ossClient.shutdown();}}}/*** 生成文件下载链接* @param objectPath OSS上的文件完整路径(如:user/templates/用户模板.xlsx)* @return 下载链接(公开Bucket返回永久链接,私有Bucket返回带签名的临时链接)*/private static String generateDownloadUrl(String objectPath) {try {// 编码文件名(处理中文/特殊字符)String encodedPath = URLEncoder.encode(objectPath, StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20"); if (isPublicBucket) {// 公开Bucket:直接拼接HTTP URLString endpointHost = endpoint.replace("https://", "");String fileUrl = String.format("https://%s.%s/%s", bucketName, endpointHost, encodedPath);log.info("文件地址:{}", fileUrl);return fileUrl; } else { // 私有Bucket:生成带签名的临时URL(有效期1小时) Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000); return ossClient.generatePresignedUrl(bucketName, objectPath, expiration).toString(); }} catch (Exception e) {log.error("生成下载链接失败", e);throw new RuntimeException("生成文件下载链接失败", e);}}}