1.背景
一个商品管理模块,在添加商品时,需要上传商品图片。
2.OSS是什么?
阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。
OSS具有与平台无关的RESTful API接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
对象存储(OSS)-阿里云帮助中心 (aliyun.com)
3.开发前提
需要在阿里云中购买开通对象存储OSS,随后创建Bucket,创建子用户等。获取到 endpoint,accessKeyId,accessKeySecret,bucketName,authKey,baseUrl.
4.前端-将图片转为Base64
界面用的是Element的Upload组件,就不赘述,主要展示转化过程。
// 勾选了商品图片,然后处理图片转化为base64
onChange(file) {
const isJPG =
file.raw.type === "image/jpg" ||
file.raw.type === "image/jpeg" ||
file.raw.type === "image/png";
if (!isJPG) {
this.$message.error("商品图片只能是 jpg/jpeg/png 格式!");
file.status = "fail";
// 图片格式不对,不显示在列表上
this.$refs.uploadDishesImage.uploadFiles.splice(0, 1);
return;
}
const isLt2M = file.size / 1024 / 1024 < 3;
if (!isLt2M) {
this.$message.error("商品图片大小不能超过3MB!");
// 图片太大,不显示在列表上
this.$refs.uploadDishesImage.uploadFiles.splice(0, 1);
return;
}
const self = this;
const reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = function (e) {
// 去掉base64前缀,例如data:image/jpeg;base64,
const img_base64 = e.target.result.split(",")[1];
self.form.imgBase64 = img_base64;
};
},
5.后端-导入依赖
第一个OSS依赖必须导入,第二个压缩图片依赖按需导入。
<!-- 阿里云OSS对象存储 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.2</version>
</dependency>
<!--压缩图片-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.13</version>
</dependency>
6.后端-OSS配置
将步骤3获得的六个参数在配置文件中写好
创建配置类
@Configuration
@ConfigurationProperties(prefix = "aliyun")
public class AliyunConfig {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String authKey;
@Bean
public OSS ossClient() {
accessKeySecret = new String(Base64.getDecoder().decode(accessKeySecret));
return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
}
7.后端-创建OSS服务类
两个基础的上传图片和删除文方法。上传图片方法中对图片进行了压缩,按需使用。
第一个参数为上传目录,不存在自动创建。
避免文件名相同,会发生覆盖原文件的情况。
@Service
public class AliyunOssService {
@Resource
private OSS ossClient;
@Resource
private AliyunConfig aliyunConfig;
/**
* 上传Base64格式的图片
*
* @param baseDir
* @param imgBase64
* @return 文件存储目录
* @throws IOException
*/
public String uploadBase64Image(String baseDir, String imgBase64) throws IOException {
if (imgBase64 == null) {
return null;
}
// Base64图片解码并转为字节数组
byte[] decodedImg = Base64.getDecoder().decode(imgBase64.getBytes(StandardCharsets.UTF_8));
// 将字节数组转为输入流
ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedImg);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 压缩图片
Thumbnails.of(inputStream)
.scale(0.9f)
.outputFormat("jpg")
.outputQuality(0.5)
.toOutputStream(outputStream);
ByteArrayInputStream swapStream = new ByteArrayInputStream(outputStream.toByteArray());
// 构造基于日期的存储目录(文件名重新编为uuid)
String filename = DateUtil.today() + "/" + UUID.fastUUID() + ".jpg";
String filePath = baseDir + filename;
// 上传至阿里云对象存储
ossClient.putObject(aliyunConfig.getBucketName(), filePath, swapStream);
return filePath;
}
/**
* 删除文件
*
* @param objectName
* @return
*/
public void delete(String objectName) {
// 根据BucketName,objectName删除文件
ossClient.deleteObject(aliyunConfig.getBucketName(), objectName);
}
}
8.使用
先判空,若上传了图片就保存在阿里云中。
//判断图片,上传图片到阿里云
/*------------------------------------------------------------*/
try {
if(!Objects.isNull(goods.getImgBase64())){
String image = aliyunOssService.uploadBase64Image("cashier/goods/", goods.getImgBase64());
goodsDO.setImgUrl(image);
}
}catch (IOException e){
e.printStackTrace();
throw new CustomException("保存商品图片时出错:" + e.getMessage());
}
/*------------------------------------------------------------*/
存入数据库的数据是这样的
需要使用的适合用配置文件中的 baseUrl 拼接 img_url的数据即可查看到图片。
成功