从零实现SpringBoot + VUE前后端分离项目中使用腾讯云COS技术!
0、前言
在这里,我基于SpringBoot + VUE
前后端分离项目,演示如何结合腾讯云的COS云存储
服务。由于不涉及任何业务逻辑,所以整体下来非常简单,前端项目不需要router、store、Axios等,只需要一个上传头像的页面,后端不需要对接数据库,只是简单的写个对接腾讯云COS和前端的接口。文章将会从零搭建项目开始,只要按照步骤一步一步做下来,小白也可以run起来哦,废话不多说,开始!
1、环境准备
大家都知道,开发环境不同或是采用的某一框架的版本不一致都很有可能是BUG的来源,所以如果在自己电脑测试,尽量确保版本和我这里的一致,一旦出现问题,多留意是不是环境不同,版本不一致造成的,切记不可盲目去百度直接各种Copy,结果未必能解决问题,反而跑偏方向,带来新的其他问题,在网络上查找技术解决方案时,多留意版本与环境问题!
1.1前端
-
Node.js(
v16.14.0
)官网:
-
npm(
8.3.1
)官网:
-
VUE(
@vue/cli 5.0.4
)官网:
-
Element - UI(
2.15.9
)官网:
注意:NPM是随同NodeJS一起安装的包管理工具,无需额外下载安装。
-
Java JDK(
1.8
)官网:
-
SpringBoot(
2.7.2
)官网:
1.3工具
-
OS:
Windows 10 专业版
-
前端IDE:
Visual Studio Code
(version 1.59) -
后端IDE:
IntelliJ IDEA
(2021.1.2)
在下面的内容中,有关代码部分,首先大部分都是直接放得最终运行的代码,虽然在编码中遇到了各种各样大大小小的坑,在处理过程中,未能完全记录其过程,但是几乎都是又注释标注的,方便大家学习。其次代码肯定不是绝对完美的,针对不同的问题,有不同的解决方案,如果有问题希望大佬指正。
2、前端开发
注意:大家需要在自己电脑提前安装好Node.js、npm、以及vueCLI,并确保正确添加到环境变量。这部分比较简单,这里不再演示。
2.1 使用VUECLI脚手架搭建项目
-
新建项目文件夹
COSDemo
-
在控制台中进入项目文件夹
COSDemo
下执行命令:$ vue create cosvue
-
-
Manually select features
-
(*) Babel
-
2.x
-
In package.json
-
N
-
-
等待项目安装相关依赖
-
$ cd cos
$ npm run serve
看到以上界面就说明前端项目搭建完成了。
2.2安装Element UI
使用Visual Studio Code
打开项目文件夹,然后进行如下操作。
-
在控制台中执行如下命令:
-
npm i element-ui -S
- 修改项目主配置文件
main.js
-
import Vue from 'vue' import App from './App.vue' // 引入ElementUI import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; // 注册到Vue Vue.use(ElementUI); Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')
最后前端项目目录结构:
2.3修改App.vue组件
为了方便起见,我们这里就直接在主页面上添加一个表单模拟添加用户信息,以及重点是上传头像到后端,然后后端对接腾讯云的COS服务,将我们的文件存储到腾讯云。所以,我这里直接在前端项目的App.vue文件中添加基础表单即可,也就意味着路由什么的根本用不到,修改后的App.vue代码如下,其他页面组件都可以删除比如components等文件夹。
<template>
<div id="app">
<el-card shadow="hover">
<el-form ref="form" :model="form" >
<el-form-item label="头像">
<el-upload
class="avatar-uploader"
action="http://localhost:8088/file/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="用户名">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密 码">
<el-input v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit" disabled>注册</el-button>
<!-- <el-button>取消</el-button> -->
</el-form-item>
<el-tag type="danger">这里其实只需要一个上传头像即可</el-tag>
<el-tag type="danger">为了丰富内容,就添加了用户名和密码</el-tag>
<el-tag type="danger">但是并没有对接后端接口</el-tag><br>
<el-tag type="success">😂😂😂😂😂😂</el-tag>
</el-form>
</el-card>
</div>
</template>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px !important;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
#app {
width: 400px;
height: 600px;
margin: 100px auto;
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
}
</style>
<script>
export default {
data() {
return {
form: {
username: '',
password: ''
},
imageUrl: ''
}
},
methods: {
onSubmit() {
console.log('submit!');
},
handleAvatarSuccess(res, file) {
// this.imageUrl = URL.createObjectURL(file.raw);
this.imageUrl = res;
this.$message.success("上传成功!");
},
beforeAvatarUpload(file) {
const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPGorPNG) {
this.$message.error('上传头像图片只能是 JPG 和 PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPGorPNG && isLt2M;
}
}
}
</script>
3、后端开发
3.0腾讯云对象存储介绍
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
官网地址:
3.1开通COS服务
(1)申请腾讯云账号:https://cloud.tencent.com/
(2)实名认证
(3)搜索COS然后开通“对象存储COS”服务
(4)进入管理控制台
(5)创建Bucket
-
进入管理控制台,找到存储桶列表, 创建存储桶
-
输入桶名称,选择:公有读取,其他默认
-
点击 桶名称,进入详情页,可测试上传文件
(6)创建API秘钥
-
进入API秘钥管理
-
新建秘钥
-
保存key 和 id 备用
3.2搭建后端项目
在IDEA中快速搭建项目。
引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 腾讯云COS依赖 -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.89</version>
</dependency>
<!-- 日期工具栏依赖 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
</dependencies>
配置文件
server.port=8088
spring.servlet.multipart.max-file-size=1024MB
spring.servlet.multipart.max-request-size=1024MB
tencent.cos.region=你选择的地区
tencent.cos.secretid=刚才记录的id
tencent.cos.secretkey=刚才记录的key
tencent.cos.bucketname=你设置的bucketName
读取配置工具类(非必须)
package cn.imyjs.utils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @Classname COSUtils
* @Description 读取配置文件application.properties中的配置
* @Date 2022/8/14 16:31
* @Created by YJS
* @WebSite www.imyjs.cn
*/
@Component
public class COSUtils implements InitializingBean {
@Value("${tencent.cos.region}")
private String region;
@Value("${tencent.cos.secretid}")
private String secretId;
@Value("${tencent.cos.secretkey}")
private String secretKey;
@Value("${tencent.cos.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 = region;
ACCESS_KEY_ID = secretId;
ACCESS_KEY_SECRET = secretKey;
BUCKET_NAME = bucketName;
}
}
Service层代码
FileService接口
package cn.imyjs.service;
import org.springframework.web.multipart.MultipartFile;
/**
* @Classname FileService
* @Description TODO
* @Date 2022/8/14 16:39
* @Created by YJS
* @WebSite www.imyjs.cn
*/
public interface FileService {
String upload(MultipartFile file);
}
FileServiceImpl实现类
package cn.imyjs.service.impl;
import cn.imyjs.service.FileService;
import cn.imyjs.utils.COSUtils;
import com.alibaba.fastjson.JSON;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.UUID;
/**
* @Classname FileServiceImpl
* @Description TODO
* @Date 2022/8/14 16:40
* @Created by YJS
* @WebSite www.imyjs.cn
*/
@Service
public class FileServiceImpl implements FileService {
@Override
public String upload(MultipartFile file) {
String endpoint = COSUtils.END_POINT;
String bucketName = COSUtils.BUCKET_NAME;
String secretId = COSUtils.ACCESS_KEY_ID;
String secretKey = COSUtils.ACCESS_KEY_SECRET;
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置 bucket 的地域
// clientConfig 中包含了设置 region, https(默认 http),超时, 代理等 set 方法
Region region = new Region(COSUtils.END_POINT);
ClientConfig clientConfig = new ClientConfig(region);
// 这里建议设置使用 https 协议
// 从 5.6.54 版本开始,默认使用了 https
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成 cos 客户端。
COSClient cosClient = new COSClient(cred, clientConfig);
try{
// 指定要上传的文件
InputStream inputStream = file.getInputStream();
// 指定文件将要存放的存储桶
// 指定文件上传到 COS 上的路径,即对象键。
String key = UUID.randomUUID().toString().replaceAll("-","")+
file.getOriginalFilename();
String dateUrl = new DateTime().toString("yyyy/MM/dd");
key = dateUrl+"/"+key;
ObjectMetadata objectMetadata = new ObjectMetadata();
PutObjectRequest putObjectRequest =
new PutObjectRequest(bucketName, key, inputStream,objectMetadata);
PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
System.out.println(JSON.toJSONString(putObjectResult));
String url = "https://"+bucketName+"."+"cos"+"."+endpoint+".myqcloud.com"+"/"+key;
return url;
} catch (Exception clientException) {
clientException.printStackTrace();
return null;
}
}
}
Controller层代码
package cn.imyjs.controller;
import cn.imyjs.service.FileService;
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;
/**
* @Classname FileContrller
* @Description TODO
* @Date 2022/8/14 16:45
* @Created by YJS
* @WebSite www.imyjs.cn
*/
@RestController
@CrossOrigin
@RequestMapping("file")
public class FileController {
@Autowired
private FileService fileService;
@PostMapping("upload")
public String uploadFile(MultipartFile file){
return fileService.upload(file);
}
}