在线教育项目之阿里云存储OOS
阿里云存储OOS&POI
课程目标
3)集成阿里云OSS【重点】
4)前端上传组件整合
1、 阿里云存储OSS
1. 对象存储OSS
为了解决海量数据存储与弹性扩容,项目中我们采用云存储的解决方案- 阿里云OSS。
1.1. 开通“对象存储OSS”服务
(1)申请阿里云账号
(2)实名认证
(3)开通“对象存储OSS”服务
(4)进入管理控制台
1.2. 创建Bucket
选择:标准存储、公共读、不开通
1.3. 上传默认头像
创建文件夹avatar,上传默认的用户头像
2. 使用SDK
https://help.aliyun.com/learn/learningpath/oss.html?spm=a2c4g.11174283.2.4.41617da2RHwBTC
2.1. 创建Maven项目
com.ujiuye
aliyun-oss
2.2. pom
<dependencies> |
2.3. 找到编码时需要用到的常量值
(1)endpoint
(2)bucketName
(3)accessKeyId
(4)accessKeySecret
2.4. 测试创建Bucket的连接
package com.ujiuye.oss; public class OSSTest { // Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "your endpoint"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "your accessKeyId"; String accessKeySecret = "your accessKeySecret"; String bucketName = "yxzx-file2"; @Test public void testCreateBucket() { // 创建OSSClient实例。 OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); // 创建存储空间。 ossClient.createBucket(bucketName); // 关闭OSSClient。 ossClient.shutdown(); } } |
3. 新建云存储微服务
3.1. 创建模块
Artifact:yxzx-oss
3.2. 配置pom.xml
<dependencies> <!--日期时间工具--> |
3.3. 配置application.properties
#服务端口 server.port=8001 #服务名 spring.application.name=yxzx-oss #环境设置:dev、test、prod spring.profiles.active=dev #阿里云 OSS #不同的服务器,地址不同 aliyun.oss.file.endpoint=your endpoint aliyun.oss.file.keyid=your accessKeyId aliyun.oss.file.keysecret=your accessKeySecret #bucket可以在控制台创建,也可以使用java代码创建 aliyun.oss.file.bucketname=yxzx-file aliyun.oss.file.filehost=avatar |
3.4. logback-spring.xml
修改日志路径
<property name="log.path" value="D:/yxzx_log/oss" /> |
3.5. 创建启动类
创建OssApplication.java
package com.yxzx.oss; @SpringBootApplication @ComponentScan(basePackages={"com.yxzx.oss","com.yxzx.common"}) public class OssApplication { public static void main(String[] args) { SpringApplication.run(OssApplication.class, args); } } |
3.6. 启动项目
报错
spring boot 会默认加载org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration这个类,
而DataSourceAutoConfiguration类使用了@Configuration注解向spring注入了dataSource bean,又因为项目(oss模块)中并没有关于dataSource相关的配置信息,所以当spring创建dataSource bean时因缺少相关的信息就会报错。
解决办法:
方法1、在@SpringBootApplication注解上加上exclude,解除自动加载DataSourceAutoConfiguration
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
方法2、common项目中mybatis-plus-boot-starter配置添加<optional>true</optional>
此种方式会引起后续的包扫描问题,后面再详解,此处先使用第一种方式
4. 实现文件上传
4.1. 从配置文件读取常量
创建常量读取工具类:ConstantPropertiesUtil.java
使用@Value读取application.properties里的配置内容
用spring的 InitializingBean 的 afterPropertiesSet 来初始化配置信息,这个方法将在所有的属性被初始化后调用。
原理说明:
原理:
首先说说spring的IOC容器初始化过程,首先Spring会定位BeanDefinition资源文件,然后会一个一个的去加载所有BeanDefinition,这里的BeanDefinition就是指的Bean的资源文件,即:在XML中配置的Bean和通过注解装配的Bean,在加载完所有BeanDefinition之后,会将这些BeanDefinition注册到一个HashMap中。到此spring的IOC初始化完成,那么依赖注入发生在哪里呢?在用户第一次向IOC容器索要Bean时才开始依赖注入过程(也可以通过配置lazy-init属性让容器初始化的时候就对Bean预实例化)那究竟afterPropertiesSet()方法的调用是在哪个时间点呢?通过查看该方法上的注释:
Invoked by a BeanFactory after it has set all bean properties supplied (and satisfied BeanFactoryAware and ApplicationContextAware).
译文:由BeanFactory在设置所有提供的bean属性(以及BeanFactoryAware和ApplicationContextAware满足)后调用。
可以看到在Bean所有的属性都被注入之后会去调用这个afterPropertiesSet()方法,其实在依赖注入完成的时候,spring会去检查这个类是否实现了InitializingBean接口,如果实现了InitializingBean接口,就会去调用这个类的afterPropertiesSet()方法。所以afterPropertiesSet()方法的执行时间点就很清楚了,发生在所有的properties被注入后。
/** |
4.2. 文件上传
创建Service接口:FileService.java
package com.yxzx.oss.service; |
实现:FileServiceImpl.java
参考SDK中的:Java->上传文件->简单上传->流式上传->上传文件流
@Service |
添加文件上传失败状态码
int FILE_UPLOAD_ERROR=20002; |
4.3. 控制层
创建controller:FileUploadController.java
@Api(description="阿里云文件管理") |
4.4. 重启oss服务
4.5. Swagger中测试文件上传
4.6. 配置Swagger
package com.yxzx.oss.config; |
5. 配置nginx反向代理
将接口地址加入nginx配置
location ~ /oss/ { proxy_pass http://localhost:8002; } |
重启nginx
nginx -s reload
6. 前端整合图片上传组件
6.1. 复制头像上传组件
从vue-element-admin复制组件:
vue-element-admin/src/components/ImageCropper vue-element-admin/src/components/PanThumb |
6.2. 前端参考实现
src/views/components-demo/avatarUpload.vue
6.3. 前端添加文件上传组件
src/views/ebs/teacher/form.vue
template:
<!-- 讲师头像 --> <el-form-item label="讲师头像"> <!-- 头衔缩略图 --> <pan-thumb :image="teacher.avatar"/> <!-- 文件上传按钮 --> <el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像 </el-button> <!-- v-show:是否显示上传组件 :key:类似于id,如果一个页面多个图片上传控件,可以做区分 :url:后台上传的url地址 @close:关闭上传组件 @crop-upload-success:上传成功后的回调 --> <image-cropper v-show="imagecropperShow" :width="300" :height="300" :key="imagecropperKey" :url="BASE_API+'/admin/oss/file/upload'" field="file" @close="close" @crop-upload-success="cropSuccess"/> </el-form-item> |
引入组件模块
Script:
import ImageCropper from '@/components/ImageCropper' import PanThumb from '@/components/PanThumb' |
6.4. 设置默认头像
config/dev.env.js中添加阿里云oss bucket地址
OSS_PATH: '"https://yxzx-file.oss-cn-beijing.aliyuncs.com"' |
组件中初始化头像默认地址
const defaultForm = { ......, avatar: process.env.OSS_PATH + '/avatar/default.jpg' } |
6.5. js脚本实现上传和图片回显
export default { components: { ImageCropper, PanThumb }, data() { return { //其它数据模型 ......, BASE_API: process.env.BASE_API, // 接口API地址 imagecropperShow: false, // 是否显示上传组件 imagecropperKey: 0 // 上传组件id } }, ......, methods: { //其他函数 ......, // 上传成功后的回调函数 cropSuccess(data) { console.log(data) this.imagecropperShow = false this.teacher.avatar = data.url // 上传成功后,重新打开上传组件时初始化组件,否则显示上一次的上传结果 this.imagecropperKey = this.imagecropperKey + 1 }, // 关闭上传组件 close() { this.imagecropperShow = false // 上传失败后,重新打开上传组件时初始化组件,否则显示上一次的上传结果 this.imagecropperKey = this.imagecropperKey + 1 } } } |
7. 测试文件上传
前后端联调,前端页面+后端代码可以调试成功!
- 点赞
- 收藏
- 关注作者
评论(0)