用自己电脑做文件存储,我想没谁愿意了吧,来来和我一起白嫖吧,伙伴们!!!😁
七牛云
:也是一个对象存储的云网站,当时用它是因为可以每次白嫖10个G的使用一个月,用完可以新开空间,接着用。如果有自己的域名的话,可以一直用。也可以省自己电脑内存捂脸(😂)很喜欢一句话:
”八小时内谋生活,八小时外谋发展“
我们:"待别日相见时,都已有所成”
放张图片先舒缓下心情啦
SpringBoot集成七牛云-实现文件上传、下载、解决报错、详细案例
一、背景
确实是每月10G,亲测有效。😁 (我不是推广人员,只是感觉平时写什么小Demo,写个作业啥的,用起来挺爽的。)
在网上找了一圈,都没有看到一个能够跑动的案例,要么太久远,要么就实现不了。最后实在没法去找了学长,他给我发了一份文档,才算学会。
我当时的功能需求:希望上传一张图片,然后能够返回这个图片的外链链接。
一直卡在返回图片外链链接上,一直报一个错误,就是不能够回显到页面上。
获取外链需要写下面这段代码。
最后才有这篇博客的出现,希望大家能够及时避坑。
二、具体步骤
2.1、工程目录
2.2、导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--七牛云-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0, 7.2.99]</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--七牛云-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0, 7.2.99]</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
2.3、yaml配置文件
server:
port: 8082
oss:
qiniu:
url: http://qs22nqygb.hn-bkt.clouddn.com # 这里如果有自己的域名就去绑定自己的 没有的就只能使用七牛云的测试域名
accessKey: 公共密钥 #
secretKey: 私钥 #
bucketName: wyhdsg #空间名
2.4、绑定配置文件
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
public class QiNiuYunConfig {
/**
* 七牛域名domain
*/
@Value("${oss.qiniu.url}")
private String url;
/**
* 七牛ACCESS_KEY
*/
@Value("${oss.qiniu.accessKey}")
private String AccessKey;
/**
* 七牛SECRET_KEY
*/
@Value("${oss.qiniu.secretKey}")
private String SecretKey;
/**
* 七牛空间名
*/
@Value("${oss.qiniu.bucketName}")
private String BucketName;
}
2.5、生成唯一图片名称的工具类
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 = "news/crush/"+ DateUtil.today() + "-" + uuid + suffix;
String path = uuid + suffix;
return path;
}
}
2.6、UploadImageService
import org.springframework.web.multipart.MultipartFile;
public interface UploadImageService {
String uploadQNImg(MultipartFile file);
String getPrivateFile(String fileKey);
boolean removeFile(String bucketName, String fileKey);
}
2.7、UploadImageServiceImpl
import com.crush.config.QiNiuYunConfig;
import com.crush.service.UploadImageService;
import com.crush.utils.StringUtil;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
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 org.springframework.web.multipart.MultipartFile;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@Service
public class UploadImageServiceImpl implements UploadImageService {
private QiNiuYunConfig qiNiuYunConfig;
// 七牛文件上传管理器
private UploadManager uploadManager;
//上传的token
private String token;
// 七牛认证管理
private Auth auth;
private BucketManager bucketManager;
public UploadImageServiceImpl(QiNiuYunConfig qiNiuYunConfig) {
this.qiNiuYunConfig = qiNiuYunConfig;
init();
}
private void init() {
// 构造一个带指定Zone对象的配置类, 注意这里的Zone.zone0需要根据主机选择
uploadManager = new UploadManager(new Configuration(Zone.zone2()));
auth = Auth.create(qiNiuYunConfig.getAccessKey(), qiNiuYunConfig.getSecretKey());
// 根据命名空间生成的上传token
bucketManager = new BucketManager(auth, new Configuration(Zone.zone2()));
token = auth.uploadToken(qiNiuYunConfig.getBucketName());
}
/*
* 上传文件
* @Param [file, key]
* @return java.lang.String
**/
@Override
public String uploadQNImg(MultipartFile file) {
try {
// 获取文件的名称
String fileName = file.getOriginalFilename();
// 使用工具类根据上传文件生成唯一图片名称
String imgName = StringUtil.getRandomImgName(fileName);
FileInputStream inputStream = (FileInputStream) file.getInputStream();
// 上传图片文件
Response res = uploadManager.put(inputStream, imgName, token, null, null);
if (!res.isOK()) {
throw new RuntimeException("上传七牛出错:" + res.toString());
}
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
// 直接返回外链地址
return getPrivateFile(imgName);
} catch (QiniuException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 获取私有空间文件
*
* @param fileKey
* @return
*/
@Override
public String getPrivateFile(String fileKey) {
String encodedFileName = null;
String finalUrl = null;
try {
encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");
String publicUrl = String.format("%s/%s", this.qiNiuYunConfig.getUrl(), encodedFileName);
long expireInSeconds = 3600;//1小时,可以自定义链接过期时间
finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return finalUrl;
}
/*
* 根据空间名、文件名删除文件
* @Param [bucketName, fileKey]
* @return boolean
**/
@Override
public boolean removeFile(String bucketName, String fileKey) {
try {
bucketManager.delete(bucketName, fileKey);
} catch (QiniuException e) {
e.printStackTrace();
}
return true;
}
}
2.8、UploadController
import com.crush.service.UploadImageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
@Slf4j
@Controller
public class UploadController {
@Resource
UploadImageService uploadImageService;
@GetMapping("/upload")
public String upload(){
return "upload";
}
@PostMapping(value = "/image")
private String upLoadImage(@RequestParam("file") MultipartFile file, Model model) {
if (!file.isEmpty()) {
String path = uploadImageService.uploadQNImg(file);
System.out.print("七牛云返回的图片链接:" + path);
model.addAttribute("link",path);
return "upload";
}
return "";
}
/*
* 这里为了方便测试才这么写的 可以根据实际需要 自己写。
* @Param
* @return java.lang.String
**/
@ResponseBody
@DeleteMapping("/remove")
public String removeFile(){
uploadImageService.removeFile("wyhdsg","0b677574afdf4a8ea1271108f1176bde.jpg");
return "删除成功";
}
}
2.9、测试页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="/image" method="post" enctype="multipart/form-data">
<label>上传图片</label>
<input type="file" name="file"/>
<input type="submit" value="上传"/>
<p>回显图片:</p>
<img th:src="${link}"/>
</form>
</body>
</html>
2.10、测试图片
这里也可以用postman测试的。
三、自言自语
🙅可爱的我。
希望这篇博客能够帮助到你。