目录
一、开通阿里云对象存储OSS
二、创建bucket
三、创建操作阿里云OSS许可证
四、用代码实现头像上传功能
五、引入相关依赖
六、创建properties配置文件
七、创建主启动类
八、启动测试一下
九、创建常量类,方便读取配置文件中关于oss的信息
十、controller类
十一、service接口,在其实现类中实现上传文件的代码
十二、启动,使用swagger测试一下
十三、优化一些问题
1、文件名重复问题
2、按日期进行分类
十四、serviceimpl完整代码
实现阿里云OSS对象存储功能,并且完成讲师头像上传功能。
这个在网上有很多教程,就不多赘述了。
直接在oss控制台里创建,也可以用代码创建。
这里注意:存储类型 选择 低频访问; 读写权限 选择 公共读
之后就可以获得阿里颁发的id和秘钥。
在service下创建子模块 service_oss
com.aliyun.oss
aliyun-sdk-oss
joda-time
joda-time
#服务端口
server.port=8002
#服务名
spring.application.name=service-oss
#环境设置:dev、test、prod
spring.profiles.active=dev
#阿里云 OSS
#不同的服务器,地址不同
aliyun.oss.file.endpoint=自己的bucket
aliyun.oss.file.keyid=自己的id
aliyun.oss.file.keysecret=自己的秘钥
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=edu-shang
@SpringBootApplication
@ComponentScan(basePackages = "com.shang")
public class OssApplication {
public static void main(String[] args) {
SpringApplication.run(OssApplication.class, args);
}
}
发现报错了:
原因:阿里云oss不需要数据库配置,而springboot启动时需要找数据库配置。
解决方法:1、加上数据库配置
2、在启动类添加属性,默认不加载数据库配置
我们采用方式二。
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) //不需要数据库,所以不加载,避免报错
再次启动,启动成功。
至于为什么要放到配置文件中,再创建类去读取,而不是直接写死在类中,希望有大神可以解答。我自己的理解是配置大于编码。
放在utils包下。
//implements InitializingBean : 当项目已启动,spring加载后,执行接口的一个方法
@Component
public class ConstantPropertiesUtils implements InitializingBean {
/**
* 读取配置文件中内容
*/
//aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
//aliyun.oss.file.keyid=LTAI5t8ks2X1yv12t8gJUUYm
//aliyun.oss.file.keysecret=YxDL1WN7cvz2SIO12CCoHSKfWpU906
//aliyun.oss.file.bucketname=edu-shang
@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;
}
}
同时又继承了InitializingBean接口,将私有变量赋值给静态公开常量,使类外也可以读到这些值。
放在controller包下。
@RestController
@RequestMapping("/eduoss/fileoss")
@CrossOrigin
public class OssController {
@Autowired
private OssService ossService;
@PostMapping
public R uploadOssFile(MultipartFile file){
//获取上传的文件 使用MultipartFile
//返回上传到oss的文件路径
String url = ossService.uploadFileAvatar(file);
return R.ok().data("url", url);
}
}
核心代码参考阿里官方给出的java SDK文档:
简单上传 - 对象存储 OSS - 阿里云
public interface OssService {
String uploadFileAvatar(MultipartFile file);
}
这里需要注意,@service注解要写在实现类上,否则会报错。
@Service
public class OssServiceImpl implements OssService {
@Override
public String uploadFileAvatar(MultipartFile file) {
try {
//因为写了工具类,可以直接用 类名.属性 调用静态变量
String endpoint = ConstantPropertiesUtils.END_POINT;
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
InputStream inputStream = file.getInputStream();
// 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
ossClient.putObject(bucketName, file.getOriginalFilename(), inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//返回上传后的文件路径
//需要把上传到阿里云OSS的路径手动拼接出来(有具体的规则)
// https://edu-shang.oss-cn-beijing.aliyuncs.com/liu.png
String url = "https://" + bucketName + "." + endpoint + "/" + file.getOriginalFilename();
return url;
} catch (Exception e){
e.printStackTrace();
return null;
}
}
}
随便找一张图片
打开阿里云oss控制台看看:
上传成功!
//在文件名称里添加随机唯一值
String uuid = UUID.randomUUID().toString().replaceAll("-",""); //去掉横杠
fileName = uuid + fileName;
//把文件按照日期进行分类
String datePath = new DateTime().toString("yyyy/MM/dd");
fileName = datePath + "/" + fileName;
@Service
public class OssServiceImpl implements OssService {
@Override
public String uploadFileAvatar(MultipartFile file) {
try {
//因为写了工具类,可以直接用 类名.属性 调用静态变量
String endpoint = ConstantPropertiesUtils.END_POINT;
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
InputStream inputStream = file.getInputStream();
String fileName = file.getOriginalFilename();
//在文件名称里添加随机唯一值
String uuid = UUID.randomUUID().toString().replaceAll("-",""); //去掉横杠
fileName = uuid + fileName;
//把文件按照日期进行分类
String datePath = new DateTime().toString("yyyy/MM/dd");
fileName = datePath + "/" + fileName;
// 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
ossClient.putObject(bucketName, fileName, inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//返回上传后的文件路径
//需要把上传到阿里云OSS的路径手动拼接出来(有具体的规则)
// https://edu-shang.oss-cn-beijing.aliyuncs.com/liu.png
String url = "https://" + bucketName + "." + endpoint + "/" + fileName;
return url;
} catch (Exception e){
e.printStackTrace();
return null;
}
}
}