文章目录
- OSS的开通 + 创建存储空间
- 使用Java向OSS中存储图片
- 使用SpringBoot+Vue+Element-ui实现图片的上传
- 后端
- 前端
OSS的开通 + 创建存储空间
首先到阿里云对象存储OSS官网开通对象存储OSS服务。
然后在阿里云首页点击控制台。
然后点击对象存储OSS。
点击创建Bucket。
创建Bucket。
注意:这里的读写权限改为公共读。因为是简单的使用OSS,所以大部分都是默认的。
Bucket命名规则
Bucket名称在OSS范围内必须全局唯一。
只能包括小写字母、数字和短划线(-)。
必须以小写字母或者数字开头和结尾。
长度为3~63个字符。
上传文件。
先扫描文件或者是将文件拖入框中,完成之后点击上传文件。
下面就是上传成功后的结果。
使用Java向OSS中存储图片
导入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
编写测试用例
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
@SpringBootTest
class OssApplicationTests {
@Test
void uploadOSS() {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-beijing.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "***";
String accessKeySecret = "***";
// 填写Bucket名称,例如examplebucket。
String bucketName = "tests-bucket-2022";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date()) + "/";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = format + UUID.randomUUID() + ".png";
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
String filePath= "E:\\笔记\\软件测试\\image\\_01.png";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
InputStream inputStream = new FileInputStream(filePath);
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, inputStream);
} catch (OSSException oe) {
} catch (ClientException ce) {
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
我们可以发现上传成功!
使用SpringBoot+Vue+Element-ui实现图片的上传
后端
该功能后端的目录结构
sql语句
CREATE TABLE `pic` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
)
导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 小辣椒 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
application.properties的配置
# mysql的相关配置
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/csdn
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mybatis配置
mybatis.mapper-locations=classpath:com/zhang/mapper/*.xml
mybatis.type-aliases-package=com.zhang.entity
# 打印sql语句
logging.level.com.zhang=debug
实体类
@Data
public class Picture {
private Integer id;
private String url;
}
dao层
@Mapper
public interface PictureDao {
void add(Picture picture);
List<Picture> list();
void delete(Integer id);
}
mapper的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhang.dao.PictureDao">
<select id="add" parameterType="com.zhang.entity.Picture">
insert into picture (url) values (#{url})
</select>
<select id="list" resultType="Picture">
select id,url from picture
</select>
<delete id="delete">
delete from picture where id = #{id}
</delete>
</mapper>
service层
public interface PictureService {
void add(Picture picture);
List<Picture> list();
void delete(Integer id);
}
@Service
public class PictureServiceImpl implements PictureService {
@Resource
private PictureDao pictureDao;
@Override
public void add(Picture picture) {
pictureDao.add(picture);
}
@Override
public List<Picture> list() {
return pictureDao.list();
}
@Override
public void delete(Integer id) {
pictureDao.delete(id);
}
}
controller层
实现图片上传的控制层
@RestController
public class OSSController {
@CrossOrigin // 跨域
@RequestMapping("/oss")
public Map<String,String> policy() {
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessId = "LTAI5t7Kp28TGsMHbS5YMMS9";
String accessKey = "vbap18qeb9xEkumxLLnQTNtJoaR320";
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-beijing.aliyuncs.com";
// 填写Bucket名称,例如examplebucket。
String bucket = "tests-bucket-2022";
// 填写Host地址,格式为https://bucketname.endpoint。
String host = "https://" + bucket + "." + endpoint;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
// 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
String dir = "test/" + format + "/";
// 创建ossClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey);
Map<String, String> respMap = new LinkedHashMap<String, String>();
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
respMap.put("accessId", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
// respMap.put("expire", formatISO8601Date(expiration));
} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
} finally {
ossClient.shutdown();
}
return respMap;
}
}
实现图片查询添加、删除的控制层
@RestController
public class PictureController {
@Resource
private PictureService pictureService;
@CrossOrigin
@RequestMapping("/list")
public List<Picture> list(){
return pictureService.list();
}
@CrossOrigin
@PostMapping(value = "/add")
public void add(@RequestBody String url){
Picture picture = new Picture();
picture.setUrl(url);
System.out.println(picture);
pictureService.add(picture);
}
@CrossOrigin
@RequestMapping("/delete/{id}")
public void delete(@PathVariable Integer id){
pictureService.delete(id);
}
}
前端
前端使用的是vue+element-ui
实现图片上传的组件
<template>
<el-upload
class="upload-demo"
:action="objData.host"
:file-list="fileList"
:data="objData"
:on-success="uploadImage"
:before-upload="ossPolicy"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</template>
<script>
export default {
data() {
return {
fileList: [],
objData:{
OSSAccessKeyId:'',
policy:'',
Signature:'',
key:'', // 文件的名字
host:'',
dir:''
},
url:''
};
},
methods:{
uploadImage(response, file){ // 图片上传成功时调用的函数
this.url = this.url + file.name;
this.submit(this.url)
},
submit(url){ // 添加图片
this.axios({
method:'post',
url:'http://localhost:8080/add',
data:url,
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})
},
ossPolicy() { // 直接上传到oss
let _self = this;
// 直接停止上传return false;
// 再上传前,进行服务器签名
return new Promise((resolve, reject) => {
// 请求后端
this.axios.get('http://localhost:8080/oss')
// 当使用箭头函数 this 指向的是外层
.then(response => {
console.log(response)
_self.objData.OSSAccessKeyId = response.data.accessId;
_self.objData.policy = response.data.policy;
_self.objData.Signature = response.data.signature;
_self.objData.dir = response.data.dir;
_self.objData.host = response.data.host; // 直传 oss 的服务器地址
_self.objData.key = response.data.dir + "${filename}"; // 文件的名字, 占位符,另一头拼接上
this.url = response.data.host + "/" + response.data.dir
resolve(true) // 继续上传
})
.catch(function (error) {
console.log(error);
reject(false) // 停止上传
})
});
},
first(){ // 查询
this.axios.get('http://localhost:8080/list')
.then(response => {
console.log(response)
this.fileList = response.data
})
.catch(function(error) {
})
}
}
}
</script>
遍历图片的组件
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="序号"
width="180">
<template slot-scope="scope">
<i class="el-icon-time"></i>
<span style="margin-left: 10px">{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column
label="图片地址"
width="180">
<template slot-scope="scope">
<el-image :src="scope.row.url"></el-image>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
name: "ListPicture",
data() {
return {
tableData: [{
id: '',
url: ''
}]
}
},
methods: {
handleDelete(index,row) {
console.log(row.id);
this.axios.get('http://localhost:8080/delete/' + row.id)
.then(response => {
this.first()
})
.catch(function(error) {
})
},
first(){
this.axios.get('http://localhost:8080/list')
.then(response => {
this.tableData = response.data
})
.catch(function(error) {
})
}
},
mounted() {
this.first();
}
}
</script>
首页
<template>
<el-container>
<el-header height="300px">
<ListPicture></ListPicture>
</el-header>
<el-main>
<Oss></Oss>
</el-main>
</el-container>
</template>
<script>
import Oss from "./Oss";
import ListPicture from "./ListPicture";
export default {
name: 'HelloWorld',
components:{Oss,ListPicture},
}
</script>