一、对象存储OSS
为了解决海量数据存储与弹性扩容,在一些项目中,我们会采用云存储的解决方案-阿里云OSS
1.1开通“对象存储OSS”服务
(1)申请阿里云账号
(2)实名认证
(3)开通“对象存储OSS”服务
(4)进入管理控制台
2、创建Bucket
使用oss首先需要创建Bucket
选择:标准存储、公共读、不开通
1.Bucket名称,自己随意取一个不重复的
2.区域,我这里选择华北2(北京)
3.如果访问不是很频繁,可以选择低频访问存储,也可以选择标准存储
4.读写权限可以选择公共读,或者公共读写,不要选择私有的,其他的默认就可以
创建完成
这是外网访问地域节点,等下要用得着
创建AccessKey
输入手机验证
查看自己的密钥
可以尝试一下上传
把文件拖到这里,或者点击
上传成功,可以查看详情
里面有图片信息以及访问路径
文档位置-->学习路径
然后点击Java SDK
里面有一系列的步骤,依赖、以及跟代码
3、创建后台项目oss-mytest
3.1这里我是用脚手架来创建
3.2下一步,填写项目名相关信息
3.3选择依赖,因为只是测试一下oss,所以在这里先导入web
3.4完整目录结构
下面贴出代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.oss.service</groupId>
<artifactId>oss-mytest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oss-mytest</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.1-jre</version>
</dependency>
<!--对象存储依赖-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.8.0.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
其中:
endpoint填写自己的外网地域访问节点
keyid跟keysecret也是自己申请的那个
bucketname是自己的bucket名称
server:
port: 8001
spring:
http:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
aliyun:
oss:
file:
endpoint: oss-cn-beijing.aliyuncs.com
keyid: LTAI4GAXk6A1gkVAEuXwjuio
keysecret: rMUFD8NcjgKJPW9WJbbylomQHwoLz7
bucketname: mo142
R类代码
//统一返回结果的类
public class R {
@ApiModelProperty(value = "是否成功")
private Boolean success;
@ApiModelProperty(value = "返回码")
private Integer code;
@ApiModelProperty(value = "返回消息")
private String message;
@ApiModelProperty(value = "返回数据")
private Map<String, Object> data = new HashMap<String, Object>();
//把构造方法私有
private R() {}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
//成功静态方法
public static R ok() {
R r = new R();
r.setSuccess(true);
r.setCode(ResultCode.SUCCESS);
r.setMessage("成功");
return r;
}
//失败静态方法
public static R error() {
R r = new R();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("失败");
return r;
}
public R success(Boolean success){
this.setSuccess(success);
return this;
}
public R message(String message){
this.setMessage(message);
return this;
}
public R code(Integer code){
this.setCode(code);
return this;
}
public R data(String key, Object value){
this.data.put(key, value);
return this;
}
public R data(Map<String, Object> map){
this.setData(map);
return this;
}
}
ResultCode代码
public interface ResultCode {
public static Integer SUCCESS = 20000; //成功
public static Integer ERROR = 20001; //失败
}
OssController代码
@RestController
@RequestMapping("/oss/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);
}
}
OssService层代码
public interface OssService {
//上传图片
String uploadFileAvatar(MultipartFile file);
}
OssServiceImpl 代码
@Service
public class OssServiceImpl implements OssService {
@Override
public String uploadFileAvatar(MultipartFile file) {
// Endpoint以北京为例,其它Region请按实际情况填写。
String endpoint = ConstantPropertiesUtils.END_POINT;
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
// <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
try {
//创建OSS实例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//获取上传文件输入流
InputStream inputStream = file.getInputStream();
// 上传文件到指定的存储空间(bucketName)并将其保存为指定的文件名称(objectName)。
String fileName = file.getOriginalFilename();
String uuid = UUID.randomUUID().toString().replaceAll("-","");
fileName = uuid+fileName;
//文件按照日期进行分类
String datePath = new DateTime().toString("yyyy/MM/dd");
fileName = datePath+"/"+fileName;
ossClient.putObject(bucketName, fileName,inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//https://doctor-mo.oss-cn-beijing.aliyuncs.com/42677e182bc90362b623564223072a7.jpg
String url = "https://"+bucketName+"."+endpoint+"/"+fileName;
return url;
} catch (IOException e) {
e.printStackTrace();
return null;
}
// 创建OSSClient实例。
}
}
/**
* @program: oss-mytest
* @description:
* @author: Mr.mo
* @create: 2020-07-21
**/
@Component
public class ConstantPropertiesUtils implements InitializingBean {
//读取配置文件中的内容
@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;
}
}
启动类代码
@SpringBootApplication
@EnableSwagger2
public class OssMytestApplication {
public static void main(String[] args) {
SpringApplication.run(OssMytestApplication.class, args);
}
}
最后启动试一下效果
启动成功,因为这里已经导入了swagger的相关依赖,所以可以直接通过swagger访问
输入链接,如图
http://localhost:8001/swagger-ui.html
可以看到了Osscontroller,点击
然后选择上传图片
我这里随便上传一张
然后点击Try it out
下面返回了一个信息,已经成功了,以及返回了一个地址,通过返回的地址,可以直接下载查看图片
去阿里云看下
点开查看详情,这里是以日期为文件夹存放的,方便管理
这样,后端上传就基本ok了
4、搭载vue+element-ui组件进行图片的上传
element-ui官网:
https://element.eleme.cn/#/zh-CN
组件上传,进行查看代码,把代码拷贝,进行修改
我这里随便弄一个前端代码进行测试
其中:我把auto-upload改成了true,让图片自动上传,方便查看效果
前端代码
<template>
<div style="padding:20px">
<el-form
:model="ruleForm"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
label-position="left"
>
<el-form-item>
<el-upload
class="upload-demo"
ref="upload"
action="http://localhost:8001/oss/fileoss"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:limit="1"
:auto-upload="true"
list-type="picture-card"
:on-change="changePicture"
:on-success="getUrl"
>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "registration",
data() {
return {
fileList: [],
ruleForm: {
url: ""
}
};
},
methods: {
// 提交
resetForm(formName) {
this.$refs[formName].resetFields();
},
// 上传到服务器(提交)
submitUpload() {
this.$refs.upload.submit();
},
// 图片被移除时触发的事件
handleRemove(file, fileList) {
console.log(file, fileList);
// 当图片列表的长度为0时,显示上传的按钮
if (fileList.length == 0) {
document.getElementsByClassName(
"el-upload--picture-card"
)[0].style.display = "inline-block";
}
},
handlePreview(file) {
console.log(file);
},
// 图片被改变时(添加、上传失败、上传成功)触发的事件
changePicture(file, fileList) {
console.log("图片被改变时:"+fileList.length);
// 当图片列表的长度为1时,隐藏上传的按钮
if (fileList.length == 1) {
document.getElementsByClassName(
"el-upload--picture-card"
)[0].style.display = "none";
}
},
// 图片上传成功后
getUrl(response, file, fileList) {
console.log("获取到的url:"+response.data.url);
//this.submitTable();
},
// 提交表单
submitTable() {
console.log("提交表单");
}
},
created() {
}
};
</script>
<style>
</style>
运行前端页面效果
此时我把阿里云的照片清空,方便等下查看效果
然后在刚刚的前端页面点击上传
f12查看控制台打印,可以看到,后台返回的地址取到了
查看阿里云
也是有照片的,证明前端上传图片成功了
其中,如果想调用后台把阿里云的图片进行删除,阿里云官方文档也是有代码的