SpringBoot整合阿里OSS实现上传下载
目录💻
前言
写该项目主要是自己编写小程序,需要进行存储一些图片以及视频,在我们进行文件存储的时候,主要可以通过纪中途径进行存储,可以选择通过转二进制直接存储在数据库,或者直接存储在前端服务器,也可以自己搭建一个文件存储系统(如minio、FastDFS等),还有就是可以存储在第三方搭建好的云存储服务器,最常用的就是阿里OSS了,也就是我使用的、拿来即用。
一、介绍
阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。
本文在使用上主要使用的springboot对阿里云OSS进行单独以及批量上传、删除对应的文件,下载一般会采用直接通过http直接连接阿里云OSS下载。
二、阿里云添加oss
1、进入oss目录
进入官网后点击控制台,注册或者登陆自己的账号
点击左上角的导航页,在选择对象存储oss
看到这样的就是你oss的主页列表了
2、创建bucket
- 添加名字(需要唯一,可以根据项目名定义);
- 地域选择自己最近的城市;
- 存储类型(根据自己情况来)
- 存储冗余类型(默认就行)
- 阻止公共访问:一般不需要开通,因为我们给前端的是链接
- 读写权限:
- 一般选择公共读:就是可以通过链接直接读取下载文件、
- 私有:就是上传下载都需要验证
- 公共读写:不选择,不安全
- 所属资源组:默认,
- 下面都也全部默认就行
点击完成创建
再点击确认、会提示创建成功
可以看到刚刚创建的
3、测试上传下载
- 双击bucket可以进入管理页面进行上传下载
- 选择文件上传
- 可以看到刚刚上传的
- 点击详情可以看到基础信息,可以通过url进行下载
4、创建AccessKey管理账号
- AccessKey列表页面
- 点击创建,会先要验证身份,验证完后就创建成功了
可以拿到,然后记得下载文件,复制好自己的,用做调用时的身份验证
<AccessKey ID和 AccessKey Secret
三、依赖以及配置
项目搭建好之后,依赖和配置除了,oss的其他的自己根据自己情况去添加
1、依赖
主要是oss的依赖以及几个基础的
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.12</version>
</dependency>
<!--oss-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<!-- SpringWeb模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
2、yml
主要要设置spring的文件上传的大小以及oss配置
# Spring配置
spring:
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 1024MB
# 设置总上传的文件大小
max-request-size: 1024MB
oss:
accessKeyId: LTAI5t**** # 到阿里云上获取的AccessKey管理账号id
endpoint: oss-cn-shanghai.aliyuncs.com # 地址,看自己选择的阿里云是哪个地方的服务器。规则: oss-cn-城市拼音.aliyuncs.com
accessKeySecret: mJCpS3kc**** # 阿里云的AccessKey管理账号Secret
bucketName: test # bucket名字
3、Config类
用作把oss客户端对象注入到bean容器,因为我们是使用springboot进行管理项目的,直接在启动的时候就建立连接,避免每次请求时建立一个新的连接,出现连接过多的问题
/**
* @projectName: lightyear_web
* @package: com.ruoyi.common.utils
* @className: OSSUtil
* 阿里oss操作工具类
* @version: 1.0
*/
@Configuration
public class OSSConfig {
// 阿里云访问地址
@Value("${oss.endpoint}")
private String endpoint ;
@Value("${oss.accessKeyId}")
private String accessKeyId ;
@Value("${oss.accessKeySecret}")
private String accessKeySecret ;
@Bean
public OSS getOSSClient(){
return new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
}
}
4、OSSUtil 工具类
/**
* @projectName: lightyear_web
* @package: com.ruoyi.common.utils
* @className: OSSUtil
* 阿里云oss上传工具类
* @version: 1.0
*/
@Slf4j
@Component
public class OSSUtil {
@Autowired
private OSS ossClient;
@Value("${oss.bucketName}")
private String bucketName ;
@Value("${oss.endpoint}")
private String endpoint ;
@Autowired
private ImageService imageService;
/**
* @param file: 文件流
* @return String
* 单个文件上传
* @date 2024/4/23 21:52
*/
public String putOssFile(MultipartFile file){
String fileName = "";
try {
InputStream inputStream = file.getInputStream();
// 获取文件名
fileName = file.getOriginalFilename();
// 名字
String imageName = IdUtils.fastSimpleUUID();
fileName = imageName + "_" + fileName;
// 文件夹路径
String drwPath = DateUtil.format(new Date(), "yyyy/MM/dd");
fileName = drwPath + "/" + fileName;
ossClient.putObject(bucketName, fileName, inputStream);
String url = "https://" + bucketName +"."+ endpoint + "/" + fileName;
Image image = new Image();
image.setId(IdUtil.getSnowflakeNextId());
image.setImgUrl(url);
image.setImgName(fileName);
image.setCreateTime(new Date());
imageService.save(image);
return image.getId().toString();
} catch (IOException e) {
log.error( "文件上传失败!----->"+fileName);
log.error(e.getMessage());
new RuntimeException(fileName+"---文件上传失败!----->"+e.getMessage());
}
return null;
}
/**
* @param fileList: 文件流
* @return String
* 多个文件上传
* @date 2024/4/23 21:52
*/
public String putOssFileList(List<MultipartFile> fileList){
String ids = "";
for (MultipartFile file : fileList) {
String id = putOssFile(file);
ids = ids + id + ",";
}
return ids;
}
/**
* @param imageId: 图片表id
* @return void
* 删除单个图片
* @date 2024/4/24 15:54
*/
public void deleteOssFile(String imageId){
Image byId = imageService.getById(imageId);
String fileName = byId.getImgName();
ossClient.deleteObject(bucketName, fileName);
imageService.removeById(byId);
}
/**
* @param imageIdS: 图片表ids
* @return void
* 删除单个图片
* @date 2024/4/24 15:54
*/
public void deleteOssFileList(String imageIdS){
String[] split = imageIdS.split(",");
List<Image> list = imageService.lambdaQuery().in(Image::getId, split).list();
List<String> fileNameList = list.stream().map(Image::getImgName).collect(Collectors.toList());
ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(fileNameList).withEncodingType("url"));
imageService.removeBatchByIds(list);
}
}
四、controller
主要4个接口、单独上传、删除的和批量上传、删除的
@RestController
@Api(tags = "上传")
@RequestMapping("/api/activitys")
public class ActivitysController extends BaseController
{
@Autowired
private OSSUtil ossUtil;
@ApiOperation("文件上传")
@PostMapping("testFile")
public AjaxResult testFile(MultipartFile file){
return success(ossUtil.putOssFile(file));
}
/**
* @param loginUserBody:
* @return AjaxResult
* 多个文件上传
* @date 2024/4/24 16:47
*/
@PostMapping("/testFileList")
@ApiOperation("多个文件上传")
public AjaxResult testFileList(@RequestParam(required = false) MultipartFile avatar,
@RequestParam MultipartFile[] qualifications,
LoginUserBody loginUserBody){
ArrayList<Object> list = new ArrayList<>();
if (qualifications != null){
List<MultipartFile> list1 = Arrays.asList(qualifications);
String id = ossUtil.putOssFileList(list1);
list.add(id);
}
if (avatar != null){
String id = ossUtil.putOssFile(avatar);
list.add(id);
}
return success(list);
}
/**
* @param imageId:
* @return AjaxResult
* 单个删除
* @date 2024/4/24 16:47
*/
@DeleteMapping("deleteFile")
public AjaxResult deleteFile(String imageId){
ossUtil.deleteOssFile(imageId);
return success();
}
/**
* @param imageIdS:
* @return AjaxResult
* 批量删除
* @date 2024/4/24 16:47
*/
@DeleteMapping("deleteFileList")
public AjaxResult deleteFileList(String imageIdS){
ossUtil.deleteOssFileList(imageIdS);
return success();
}
}
五、测试
1、测试上传
通过postman进行上传测试、可以一次性上传多一个或者多个文件,返回最后存储到数据库表中的对应记录的id
- 批量删除
如果在对应的路径下可以看到文件那说明上传成功了
存储到数据库的url,可以直接通过浏览器下载,说明地址也没问题了
2、测试删除
通过id进行删除对应的