目录
一、开通阿里云对象存储OSS
二、创建bucket
三、创建操作阿里云OSS许可证
四、用代码实现头像上传功能
五、引入相关依赖
六、创建properties配置文件
七、创建主启动类
八、启动测试一下
九、创建常量类,方便读取配置文件中关于oss的信息
十、controller类
十一、service接口,在其实现类中实现上传文件的代码
十二、启动,使用swagger测试一下
十三、优化一些问题
1、文件名重复问题
2、按日期进行分类
十四、serviceimpl完整代码
实现阿里云OSS对象存储功能,并且完成讲师头像上传功能。
一、开通阿里云对象存储OSS
这个在网上有很多教程,就不多赘述了。
二、创建bucket
直接在oss控制台里创建,也可以用代码创建。
这里注意:存储类型 选择 低频访问;读写权限 选择 公共读
三、创建操作阿里云OSS许可证
之后就可以获得阿里颁发的id和秘钥。
四、用代码实现头像上传功能
在service下创建子模块 service_oss
五、引入相关依赖
<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>
六、创建properties配置文件
#服务端口server.port=8002#服务名spring.application.name=service-oss#环境设置:dev、test、prodspring.profiles.active=dev#阿里云 OSS#不同的服务器,地址不同aliyun.oss.file.endpoint=自己的bucketaliyun.oss.file.keyid=自己的idaliyun.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)//不需要数据库,所以不加载,避免报错
再次启动,启动成功。
九、创建常量类,方便读取配置文件中关于oss的信息
至于为什么要放到配置文件中,再创建类去读取,而不是直接写死在类中,希望有大神可以解答。我自己的理解是配置大于编码。
放在utils包下。
//implements InitializingBean : 当项目已启动,spring加载后,执行接口的一个方法@Componentpublic class ConstantPropertiesUtils implements InitializingBean {/*** 读取配置文件中内容*///aliyun.oss.file.endpoint=oss-cn-//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;@Overridepublic void afterPropertiesSet() throws Exception {END_POINT = endpoint;ACCESS_KEY_ID = keyid;ACCESS_KEY_SECRET = keysecret;BUCKET_NAME = bucketname;}}
同时又继承了InitializingBean接口,将私有变量赋值给静态公开常量,使类外也可以读到这些值。
十、controller类
放在controller包下。
@RestController@RequestMapping("/eduoss/fileoss")@CrossOriginpublic class OssController {@Autowiredprivate OssService ossService;@PostMappingpublic R uploadOssFile(MultipartFile file){//获取上传的文件 使用MultipartFile//返回上传到oss的文件路径String url = ossService.uploadFileAvatar(file);return R.ok().data("url", url);}}
十一、service接口,在其实现类中实现上传文件的代码
核心代码参考阿里官方给出的java SDK文档:
简单上传 - 对象存储 OSS - 阿里云
public interface OssService {String uploadFileAvatar(MultipartFile file);}
这里需要注意,@service注解要写在实现类上,否则会报错。
@Servicepublic class OssServiceImpl implements OssService {@Overridepublic 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-/liu.pngString url = "https://" + bucketName + "." + endpoint + "/" + file.getOriginalFilename();return url;} catch (Exception e){e.printStackTrace();return null;}}}
十二、启动,使用swagger测试一下
随便找一张图片
打开阿里云oss控制台看看:
上传成功!
十三、优化一些问题
1、文件名重复问题
//在文件名称里添加随机唯一值String uuid = UUID.randomUUID().toString().replaceAll("-",""); //去掉横杠fileName = uuid + fileName;
2、按日期进行分类
//把文件按照日期进行分类String datePath = new DateTime().toString("yyyy/MM/dd");fileName = datePath + "/" + fileName;
十四、serviceimpl完整代码
@Servicepublic class OssServiceImpl implements OssService {@Overridepublic 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-/liu.pngString url = "https://" + bucketName + "." + endpoint + "/" + fileName;return url;} catch (Exception e){e.printStackTrace();return null;}}}