文章目录
一、阿里云OSS集成
步骤一:创建阿里云OSS账号
在开始集成阿里云OSS之前,确保您已在阿里云官网注册了账号,并创建了一个OSS存储空间(Bucket)。具体操作步骤可参考阿里云官方文档。
步骤二:获取AccessKeyId和AccessKeySecret
- 登录阿里云控制台。
- 前往 “访问控制” > “用户管理”。
- 创建一个新的Access Key,记录下
AccessKeyId
和AccessKeySecret
,这些将用于Java应用程序的身份验证。
步骤三:添加阿里云OSS SDK依赖
在您的Java项目中添加阿里云OSS SDK的依赖。您可以使用Maven或Gradle等构建工具。以下是Maven的示例:
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.sdk.oss}</version>
</dependency>
确保在pom.xml
中定义了${aliyun.sdk.oss}
的具体版本号,例如3.13.2
。
步骤四:编写AliOssUtil工具类
创建一个配置类用于管理阿里云OSS的相关属性:
package com.example.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {
@NotNull
private String endpoint;
@NotNull
private String accessKeyId;
@NotNull
private String accessKeySecret;
@NotNull
private String bucketName;
}
接着,编写AliOssUtil
工具类,用于处理文件上传逻辑:
package com.example.util;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.ClientException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
/**
* 文件上传
*
* @param bytes 文件字节数组
* @param objectName 文件在OSS中的名称
* @return 文件访问路径
*/
public String upload(byte[] bytes, String objectName) {
try (OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret)) {
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} catch (OSSException oe) {
log.error("OSSException: {}", oe.getErrorMessage());
// 根据需要重新抛出异常或返回特定的错误信息
} catch (ClientException ce) {
log.error("ClientException: {}", ce.getMessage());
// 根据需要重新抛出异常或返回特定的错误信息
}
String fileUrl = String.format("https://%s.%s/%s", bucketName, endpoint, objectName);
log.info("文件上传到: {}", fileUrl);
return fileUrl;
}
}
步骤五:编写阿里云OSS接口代码
创建一个配置类,将AliOssUtil
注入为Bean:
package com.example.config;
import com.example.util.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@Configuration
@Slf4j
public class OssConfiguration {
@Bean
@ConditionalOnMissingBean
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
log.info("开始创建阿里云文件上传工具类对象,{}", aliOssProperties);
return new AliOssUtil(
aliOssProperties.getEndpoint(),
aliOssProperties.getAccessKeyId(),
aliOssProperties.getAccessKeySecret(),
aliOssProperties.getBucketName()
);
}
}
接下来,编写控制器类,提供文件上传接口:
package com.example.controller;
import com.example.util.AliOssUtil;
import com.example.common.Result;
import com.example.constant.MessageConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
@RestController
@RequestMapping("/admin/common/")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {
@Autowired
private AliOssUtil aliOssUtil;
@PostMapping("/upload")
@ApiOperation("文件上传")
public Result<String> upload(@RequestParam("file") MultipartFile file){
log.info("文件上传,{}", file.getOriginalFilename());
if (file.isEmpty()) {
return Result.error("文件不能为空");
}
try {
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = UUID.randomUUID().toString() + extension;
String filePath = aliOssUtil.upload(file.getBytes(), objectName);
if (filePath != null) {
return Result.success(filePath);
} else {
return Result.error(MessageConstant.UPLOAD_FAILED);
}
} catch (IOException e) {
log.error("文件上传失败,{}", e.getMessage());
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}
}
二、七牛云OSS集成
步骤一:添加七牛云OSS SDK依赖
在Java项目中添加七牛云OSS SDK的依赖。以下是Maven的示例:
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.7.0</version>
</dependency>
同时,确保引入七牛云SDK所需的第三方库:
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>happy-dns-java</artifactId>
<version>0.1.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
步骤二:编写七牛云OSS上传逻辑
首先,配置七牛云OSS的相关属性。在application.yml
中添加:
sky:
qiniuoss:
accessKey: pcd2zT**205L**c8492a86Z**Oeov***XO7WO***
secretKey: Bu-rtiGv**Krb***gPD3ARSlJoXKe3P***Lags-w
bucket: your-bucket-name
domain: http://your-domain.com
接下来,编写上传服务接口及其实现类:
上传服务接口
package com.example.service;
import org.springframework.web.multipart.MultipartFile;
public interface UploadService {
String upload(MultipartFile file);
}
上传服务实现类
package com.example.service.impl;
import com.example.service.UploadService;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
@Service
@ConfigurationProperties(prefix = "sky.qiniuoss")
@Data
@Slf4j
public class UploadServiceImpl implements UploadService {
private String accessKey;
private String secretKey;
private String bucket;
private String domain;
private UploadManager uploadManager;
private Auth auth;
@PostConstruct
public void init() {
Configuration cfg = new Configuration(Region.autoRegion());
cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
this.uploadManager = new UploadManager(cfg);
this.auth = Auth.create(accessKey, secretKey);
}
@Override
public String upload(MultipartFile file) {
if (file.isEmpty()) {
log.error("上传文件为空");
return null;
}
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
String filePath = UUID.randomUUID().toString() + extension;
return uploadOss(file, filePath);
}
private String uploadOss(MultipartFile img, String filePath) {
String key = filePath;
try (InputStream inputStream = img.getInputStream()) {
String upToken = auth.uploadToken(bucket);
Response response = uploadManager.put(inputStream, key, upToken, null, null);
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
String fileUrl = String.format("%s/%s", domain, putRet.key);
log.info("文件上传成功: {}", fileUrl);
return fileUrl;
} catch (QiniuException ex) {
Response r = ex.response;
log.error("七牛云上传异常: {}", r.toString());
try {
log.error("七牛云响应: {}", r.bodyString());
} catch (QiniuException ex2) {
// 忽略
}
} catch (IOException e) {
log.error("文件读取异常: {}", e.getMessage());
}
return null;
}
}
控制器类
package com.example.controller;
import com.example.service.UploadService;
import com.example.common.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/admin/common/")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {
@Autowired
private UploadService uploadService;
@PostMapping("/upload")
@ApiOperation("文件上传")
public Result<String> upload(@RequestParam("file") MultipartFile file){
log.info("文件上传,{}", file.getOriginalFilename());
if (file.isEmpty()) {
return Result.error("文件不能为空");
}
String filePath = uploadService.upload(file);
if (filePath != null) {
return Result.success(filePath);
} else {
return Result.error("文件上传失败");
}
}
}
三、其他事项
统一配置管理
在不同的OSS集成部分,使用统一的配置文件格式和命名规范。例如,阿里云OSS使用sky.alioss
前缀,七牛云OSS使用sky.qiniuoss
前缀。这样可以保持配置的一致性和可维护性。
sky:
alioss:
endpoint: your-alibaba-endpoint
accessKeyId: your-access-key-id
accessKeySecret: your-access-key-secret
bucketName: your-bucket-name
qiniuoss:
accessKey: your-qiniu-access-key
secretKey: your-qiniu-secret-key
bucket: your-qiniu-bucket
domain: http://your-qiniu-domain.com
错误处理和日志记录
在上传文件时,详细记录错误信息,以便于调试和维护。确保在所有异常捕获块中记录足够的信息,并根据需要采取相应的处理措施。
安全性考虑
-
敏感信息保护:确保
application.yml
或application.properties
文件中不直接暴露敏感信息(如accessKey
和secretKey
)。可以使用环境变量、加密配置或配置管理工具(如Spring Cloud Config)来增强安全性。 -
权限管理:为不同的服务和用户分配最小权限,避免过度授权。
统一接口抽象
如果未来需要支持更多的OSS提供商,可以考虑定义一个统一的上传接口,并为每个OSS提供商实现该接口。这有助于代码的扩展和维护。
public interface OssService {
String upload(MultipartFile file);
}
@Service
public class AliOssServiceImpl implements OssService {
// 实现阿里云OSS的上传逻辑
}
@Service
public class QiniuOssServiceImpl implements OssService {
// 实现七牛云OSS的上传逻辑
}
通过依赖注入,您可以在控制器中灵活选择使用哪种OSS服务。
接口参数校验
使用注解如@Valid
和自定义验证注解,确保上传的文件符合预期的格式和大小。
@PostMapping("/upload")
@ApiOperation("文件上传")
public Result<String> upload(@RequestParam("file") @NotNull @Size(max = 5 * 1024 * 1024) MultipartFile file){
// 上传逻辑
}