阿里云控制台的操作
- 首先在阿里云官网开通oss对象存储
- 然后创建一个Bucket
- 点击文件管理可上传文件
- 创建id和秘钥
使用方式参考官方文档
https://help.aliyun.com/document_detail/32008.html?spm=5176.208357.1107607.22.754e390fcvGWbV
- 引入依赖
<dependencies>
<!-- 阿里云oss依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
<!-- 日期工具栏依赖 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
</dependencies>
- 添加配置文件
#服务端口
server.port=8002
#服务名
spring.application.name=service-oss
#环境设置:dev、test、prod
spring.profiles.active=dev
#阿里云 OSS
#不同的服务器,地址不同
aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
aliyun.oss.file.keyid=LTAI4GCBSGzKJi
aliyun.oss.file.keysecret=NYH0iN5pZvtEv
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=edu-star
对于idea没有配置数据库信息启动报错的解决方式
第一种方式 , 添加数据库配置
第二种方式 , 在启动类中添加注解@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
- 创建常量类 , 读取配置文件内容
package com.starcpdk.edu.oss.utils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//当项目启动时 , spring中的接口InitializingBean , spring加载之后 , 执行接口中的一个方法
@Component
public class ConstantPropertiesUtils implements InitializingBean {
//读取配置文件内容
@Value("${aliyun.oss.file.endpoint}")//属性注入
private String endpoint;
@Value("${aliyun.oss.file.keyid}")//属性注入
private String keyId;
@Value("${aliyun.oss.file.keysecret}")//属性注入
private String keySecret;
@Value("${aliyun.oss.file.bucketname}")//属性注入
private String bucketName;
//定义公开静态的常量
public static String END_POINT;
public static String ACCESS_KEY_ID;
public static String ACCESS_KEY_SECRET;
public static String BUCKET_NAME;
@Override
public void afterPropertiesSet() throws Exception { // 上边的属性注入加载完成之后该方法就会执行
END_POINT = endpoint;
ACCESS_KEY_ID = keyId;
ACCESS_KEY_SECRET = keySecret;
BUCKET_NAME = bucketName;
}
}
- 添加service 、 controller
OssController
package com.starcpdk.edu.oss.controller;
import com.starcpdk.edu.commonutils.R;
import com.starcpdk.edu.oss.service.OssService;
import com.starcpdk.edu.oss.service.impl.OssServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@CrossOrigin
@Api(value = "oss对象存储")
@RestController
@RequestMapping("/eduoss/fileoss")
public class OssController {
@Autowired
private OssService ossService;
//上传头像的方法
@ApiOperation(value = "上传头像的方法")
@PostMapping
public R uploadOssFile(MultipartFile file){
//获取上传的文件 , MultipartFile
//返回上传到OSs的路径
String url = ossService.uploadFileAvatar(file);
return R.ok().data("url" , url);
}
}
OssServiceImpl
package com.starcpdk.edu.oss.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.starcpdk.edu.oss.service.OssService;
import com.starcpdk.edu.oss.utils.ConstantPropertiesUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.FileInputStream;
import java.io.InputStream;
@Service
public class OssServiceImpl implements OssService {
//上传头像到oss
@Override
public String uploadFileAvatar(MultipartFile file) {
//工具类获取值
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = ConstantPropertiesUtils.END_POINT;
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
//bucketName的名字
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
try{
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 获取上传文件输入流。
InputStream inputStream = file.getInputStream();
//获取文件的名称
String fileName = file.getOriginalFilename();
//调用oss方法实现上传
//第一个参数 Bucket名称
//第二个参数 上传到oss文件路径和文件名称 aa/bb/1.jpg
//第三个参数 上传文件输入流
ossClient.putObject(bucketName, fileName, inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//把上传之后的文件路径返回
//需要把上传到阿里云oss路径手动拼接出来
String url = "";
url = "https://" + bucketName + "." + endpoint + "/" + fileName;
return url;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
OssService
package com.starcpdk.edu.oss.service;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Service
public interface OssService {
String uploadFileAvatar(MultipartFile file);
}
存在两个问题
- 文件名称重复会造成覆盖
- 文件都存在根录下会造成文件很乱
解决方式
- 给文件名称加一个随机值
- 给文件按日期进行分类
具体实现
为文件名称加一个随机的唯一的字符串拼接到文件名后边 , 使用uuid生成随机的唯一的字符串
在获取文件名称后添加如下代码
//在文件名称中添加随机唯一值 , uuid生成的值为saasa-sxda-sdas-da , 想去掉- , 用.replace方法将-替换为空字符串
String uuid = UUID.randomUUID().toString().replace("-" , "");
//例子为 yuyusxs01.jpg
fileName = uuid + fileName;
将文件按照时间分类存储到oss中
//2. 把文件按照时间进行分类
//2020/06/29/01.jpg
//获取当前日期
//2020/06/29
String dataPath = new DateTime().toString("yyyy/mm/dd");
//拼接
fileName = dataPath + "/" + fileName;
DateTime()类是引入的以下依赖中的类
<!-- 日期工具栏依赖 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
完整的OssServiceImpl类
package com.starcpdk.edu.oss.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.starcpdk.edu.oss.service.OssService;
import com.starcpdk.edu.oss.utils.ConstantPropertiesUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.UUID;
@Service
public class OssServiceImpl implements OssService {
//上传头像到oss
@Override
public String uploadFileAvatar(MultipartFile file) {
//工具类获取值
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = ConstantPropertiesUtils.END_POINT;
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
//bucketName的名字
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
try{
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 获取上传文件输入流。
InputStream inputStream = file.getInputStream();
//获取文件的名称
String fileName = file.getOriginalFilename();
//1. 在文件名称中添加随机唯一值 , uuid生成的值为saasa-sxda-sdas-da , 想去掉- , 用.replace方法将-替换为空字符串
String uuid = UUID.randomUUID().toString().replace("-" , "");
//例子为 yuyusxs01.jpg
fileName = uuid + fileName;
//2. 把文件按照时间进行分类
//2020/06/29/01.jpg
//获取当前日期
//2020/06/29
String dataPath = new DateTime().toString("yyyy/mm/dd");
//拼接
fileName = dataPath + "/" + fileName;
//调用oss方法实现上传
//第一个参数 Bucket名称
//第二个参数 上传到oss文件路径和文件名称 aa/bb/1.jpg
//第三个参数 上传文件输入流
ossClient.putObject(bucketName, fileName, inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//把上传之后的文件路径返回
//需要把上传到阿里云oss路径手动拼接出来
String url = "";
url = "https://" + bucketName + "." + endpoint + "/" + fileName;
return url;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}