Springboot整合七牛云存储实现图片上传(详细)
目录
本文参考:https://blog.csdn.net/weixin_41922289/article/details/90315999
创建Springboot工程
配置依赖
<?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 http://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.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.duck.code</groupId>
<artifactId>Springboot Qiniu</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- springboot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!--七牛-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.7</version>
</dependency>
<!--工具包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.3</version>
</dependency>
</dependencies>
</project>
配置yml配置文件
server:
port: 8082
# 七牛云存储
oss:
qiniu:
domain: http://qdnolc9h2.bkt.clouddn.com # 访问域名(默认使用七牛云测试域名)
accessKey: LbO-QxxxxxxxxoF4H3p # 公钥
secretKey: TyJAtXx7xxxx_gxbA5k # 私钥
bucketName: codeduck #存储空间名称
创建配置类获取yml配置文件信息
package com.duck.code.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* CloudStorageConfig
* @description 云存储配置类
*/
@Data
@Configuration
public class CloudStorageConfig {
/**
* 七牛域名domain
*/
@Value("${oss.qiniu.domain}")
private String qiniuDomain;
/**
* 七牛ACCESS_KEY
*/
@Value("${oss.qiniu.accessKey}")
private String qiniuAccessKey;
/**
* 七牛SECRET_KEY
*/
@Value("${oss.qiniu.secretKey}")
private String qiniuSecretKey;
/**
* 七牛空间名
*/
@Value("${oss.qiniu.bucketName}")
private String qiniuBucketName;
}
创建工具类StringUtil
在
StringUtil
中创建方法getRandomImgName(String fileName)
根据上传文件名称,使用UUID生成唯一的图片名称
,防止命名冲突
package com.duck.code.utils;
import cn.hutool.core.date.DateUtil;
import java.util.UUID;
/**
* @program: codeduck
* @description:
* @author: CodeDuck
* @create: 2020-07-30 09:39
**/
public class StringUtil {
/**
* @Description: 生成唯一图片名称
* @Param: fileName
* @return: 云服务器fileName
*/
public static String getRandomImgName(String fileName) {
int index = fileName.lastIndexOf(".");
if ((fileName == null || fileName.isEmpty()) || index == -1){
throw new IllegalArgumentException();
}
// 获取文件后缀
String suffix = fileName.substring(index);
// 生成UUID
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
// 生成上传至云服务器的路径
String path = "code/duck/" + DateUtil.today() + "-" + uuid + suffix;
return path;
}
}
创建抽象类UploadImageService
package com.duck.code.service;
import com.duck.code.config.CloudStorageConfig;
import java.io.FileInputStream;
/**
* @program: Springboot Qiniu
* @description:
* @author: CodeDuck
* @create: 2020-07-30 19:48
**/
public abstract class UploadImageService {
protected CloudStorageConfig config;
public abstract String uploadQNImg(FileInputStream file, String path);
}
实现抽象类UploadImageService
实现抽象类的具体功能
package com.duck.code.service.impl;
import com.duck.code.config.CloudStorageConfig;
import com.duck.code.service.UploadImageService;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.stereotype.Service;
import java.io.FileInputStream;
/**
* @program: Springboot Qiniu
* @description:
* @author: CodeDuck
* @create: 2020-07-30 19:51
**/
@Service
public class UploadImageServiceImpl extends UploadImageService {
// 七牛文件上传管理器
private UploadManager uploadManager;
private String token;
// 七牛认证管理
private Auth auth;
public UploadImageServiceImpl(CloudStorageConfig config){
this.config = config;
init();
}
private void init(){
// 构造一个带指定Zone对象的配置类, 注意这里的Zone.zone0需要根据主机选择
uploadManager = new UploadManager(new Configuration(Zone.zone0()));
auth = Auth.create(config.getQiniuAccessKey(), config.getQiniuSecretKey());
// 根据命名空间生成的上传token
token = auth.uploadToken(config.getQiniuBucketName());
}
@Override
public String uploadQNImg(FileInputStream file, String key) {
try{
// 上传图片文件
Response res = uploadManager.put(file, key, token, null, null);
if (!res.isOK()) {
throw new RuntimeException("上传七牛出错:" + res.toString());
}
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
String path = config.getQiniuDomain() + "/" + putRet.key;
// 这个returnPath是获得到的外链地址,通过这个地址可以直接打开图片
return path;
}catch (QiniuException e){
e.printStackTrace();
}
return "";
}
}
创建Web访问空间实现文件上传
package com.duck.code.controller;
import com.duck.code.service.UploadImageService;
import com.duck.code.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @program: SpringBoot Qiniu
* @description:
* @author: CodeDuck
* @create: 2020-07-30 16:12
**/
@Slf4j
@RestController
@RequestMapping("/qiniu")
public class UploadController {
@Resource
UploadImageService uploadImageService;
@PostMapping(value = "/image")
private String upLoadImage(@RequestParam("file") MultipartFile file) throws IOException {
// 获取文件的名称
String fileName = file.getOriginalFilename();
// 使用工具类根据上传文件生成唯一图片名称
String imgName = StringUtil.getRandomImgName(fileName);
if (!file.isEmpty()) {
FileInputStream inputStream = (FileInputStream) file.getInputStream();
String path = uploadImageService.uploadQNImg(inputStream, imgName);
System.out.print("七牛云返回的图片链接:" + path);
return path;
}
return "上传失败";
}
}
创建静态访问Web页面index.html
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<script>
/**
* 上传图片
*/
function uploadImg() {
/**
* formData在jquey中使用需要设置:
* processData: false, // 告诉jQuery不要去处理发送的数据
* contentType: false // 告诉jQuery不要去设置Content-Type请求头
* @type {null}
*/
var fd = new FormData();
// 第一个参数为controller 接收的参数名称 , input的id
fd.append("file", document.getElementById("inputId").files[0]);
$.ajax({
url: "http://localhost:8082/qiniu/image",
type: "post",
data: fd,
processData: false,
contentType: false,
success: function (res) {
console.log(res);
if (res.status.code == 0) {
if (!$('#img').empty()) {
$('#img').empty();
}
// 这一串代码复制不上来 ,截图在下面
$('#img').append(" ![](+res.result[0]+)");
} else {
alert("图片上传失败");
}
},
dataType: "json"
})
}
</script>
<div id="img" style="margin: 200px">
<input type="file" name="text" id="inputId">
<br/><br/>
<input type="submit" onclick="uploadImg()">
</div>
</body>
</html>
测试
web访问:
后台打印上传路径