对象存储OSS
-
为了解决海量数据存储与弹性扩容,项目中采用云存储的解决方案 - 阿里云OSS
(1)打开阿里云网站,注册账号,最好用支付宝注册,因为需要实名认证 (2)使用注册的用户登录阿里云,充个几毛钱 (3)找到阿里云OSS并开通 (4)在OSS管理控制台创建bucket (5)创建操作阿里云oss许可证(阿里云颁发的id和密钥)
后端配置阿里云OSS
-
在父工程service模块下面创建子模块service_oss
(1)选择maven类型 (2)输入模块名称 service_oss
-
在service_oss中引入oss依赖
(1)guli_parent/pom.xml中配置oss版本
<properties> ... <aliyun.oss.version>2.8.3</aliyun.oss.version> ... </properties>
(2)service_oss/pom.xml中引入oss依赖
<dependencies> <!-- 阿里云oss依赖 --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency> ... </dependencies>
-
在service_oss/src/main/resources/中创建application.properties
#服务端口 server.port=8002 #服务名 spring.application.name=service-oss #环境设置:dev、test、prod spring.profiles.active=dev #阿里云 OSS #不同的服务器,地址不同 #keyid和keysecret前面后面均不能加多余的空格 aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com aliyun.oss.file.keyid=LTAI5t9AwGvbmLu41EPdPvQi aliyun.oss.file.keysecret=yC93McqdcpDgoRDlrGMeIw1aast8IY #bucket可以在控制台创建,也可以使用java代码创建 aliyun.oss.file.bucketname=edu-jh
-
在service_oss/src/main/java中创建包com.atguigu.oss,在包中创建启动类OssApplication
// 启动的时候,会去找数据库的配置,但是现在模块由于不需要操作数据库,只是做上传到oss功能,因此没有配置数据库 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) // 在启动类添加exclude属性,默认不去加载数据库配置 @ComponentScan(basePackages = {"com.atguigu"}) public class OssApplication { public static void main(String[] args) { SpringApplication.run(OssApplication.class, args); } }
上传讲师头像后端接口
-
创建包com.atguigu.oss.utils,在包中创建常量类ConstantPropertiesUtils,读取配置文件内容
@Component // 把该类交给spring管理 public class ConstantPropertiesUtils implements InitializingBean { // 实现InitializingBean接口,spring加载之后,执行接口一个方法 // 读取配置文件内容 @Value("${aliyun.oss.file.endpoint}") // 配置文件key的名称(key-value) 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_POIND; public static String ACCESS_KEY_ID; public static String ACCESS_KEY_SECRET; public static String BUCKET_NAME; @Override public void afterPropertiesSet() throws Exception { END_POIND = endpoint; ACCESS_KEY_ID = keyId; ACCESS_KEY_SECRET = keySecret; BUCKET_NAME = bucketName; } }
-
在包com.atguigu.oss中写controller和service
(1)创建包com.atguigu.oss.controller,在包中创建类OssController
@RestController // 交给spring管理,返回json数据 @RequestMapping("/eduoss/fileoss") @CrossOrigin // 解决跨域 public class OssController { @Autowired private OssService ossService; // 注入service // 上传头像的方法 @PostMapping public R uploadOssFile(MultipartFile file) { // 获取上传文件 String url = ossService.uploadFileAvatar(file); // 返回上传到oss的路径 return R.ok().data("url",url); } }
(2)创建包com.atguigu.oss.service,在包中创建接口OssService
public interface OssService { String uploadFileAvatar(MultipartFile file); }
(3)创建包com.atguigu.oss.service.impl,在包中写接口OssService的实现类
@Service public class OssServiceImpl implements OssService { @Override public String uploadFileAvatar(MultipartFile file) { // 上传头像到oss // 工具类获取值 String endpoint = ConstantPropertiesUtils.END_POIND; String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID; String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET; String bucketName = ConstantPropertiesUtils.BUCKET_NAME; try { OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 创建OSS实例 InputStream inputStream = file.getInputStream(); // 获取上传文件输入流 String fileName = file.getOriginalFilename(); // 获取文件名称 // 在文件名称里面添加随机唯一的值 String uuid = UUID.randomUUID().toString().replaceAll("-",""); fileName = uuid+fileName; // yuy76t5rew01.jpg // 把文件按照日期进行分类 String datePath = new DateTime().toString("yyyy/MM/dd"); // 获取当前日期 fileName = datePath+"/"+fileName; // 拼接 // 调用oss方法实现上传 ossClient.putObject(bucketName, fileName, inputStream); ossClient.shutdown(); // 关闭OSSClient // 把上传之后文件路径返回 return "https://"+bucketName+"."+endpoint+"/"+fileName; } catch(Exception e) { e.printStackTrace(); return null; } } }
上传讲师头像前端实现
-
创建上传组件,实现上传(ajax默认不支持直接上传文件)
在src/components中添加组件ImageCropper和PanThumb
-
在views/edu/teacher/save.vue中,使用上传组件
(1)属性
v-show:是否显示上传组件 :key:类似于id,如果一个页面多个图片上传控件,可以做区分 :url:后台上传的url地址 @close:关闭上传组件 @crop-upload-success:上传成功后的回调
(2)代码
<!-- 讲师头像:TODO --> <el-form-item label="讲师头像"> <pan-thumb :image="teacher.avatar"/> <el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像</el-button> <image-cropper v-show="imagecropperShow" :width="300" :height="300" :key="imagecropperKey" :url="BASE_API+'/eduoss/fileoss'" field="file" @close="close" @crop-upload-success="cropSuccess"/> </el-form-item>
-
引入组件
import ImageCropper from '@/components/ImageCropper' import PanThumb from '@/components/PanThumb'
-
声明组件和使用组件
export default { components: { ImageCropper, PanThumb }, // 声明组件 data() { return { // 使用组件 ... imagecropperShow:false, // 上传弹框组件是否显示 imagecropperKey:0, // 上传组件key值 BASE_API:process.env.BASE_API, // 获取dev.env.js里面地址 ... } }, methods:{ close() { // 关闭上传弹框的方法 this.imagecropperShow = false this.imagecropperKey = this.imagecropperKey+1 // 上传组件初始化 }, cropSuccess(data) { // 上传成功方法 this.imagecropperShow = false this.teacher.avatar = data.url // 上传之后接口返回图片地址 this.imagecropperKey = this.imagecropperKey+1 }, ... } }