springboot集成七牛云上传文件

大体思路

上传

前端上传MultipartFile file 文件

进行名字空值校验和格式校验,大概就是判断后缀是不是属于jpg.png

生成唯一uuid名称,然后拿着这个文件名和图片文件File调接口

接口参数为

  • 输入流inputstream,将file化流传输
  • 文件名
  • 上传token,由access,secretKey,bucket生成,还可以指定过期时间,其他额外配置,该配置我们单独搞一个配置类注册bean后续注入即可

完事之后拼接url,https(fileAccess)+www.zzz.cn/47.11.11.1(domain)+文件名path丢给前端展示

这里上传失败还可以进行重重

删除

传文件名,bucket,调接口

代码如下

依赖

  <!--        七牛云依赖--><dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.2.28</version></dependency>

application.yml格式

# ========================== ↓↓↓↓↓↓ 七牛云配置 ↓↓↓↓↓↓ ==========================
qiniu:accessKey: xxxxsecretKey: xxxx# 对象储存bucket: xxx # 空间名称zone: huanan # 存储区域domain: cdn.988.cn # 访问域名fileAccess: https://  没有ssl认证就http://

具体实现

service

package com.zww.service;import com.qiniu.common.QiniuException;
import org.springframework.web.multipart.MultipartFile;/*** @author pangpi*/
public interface FileService {/*** 上传图片到OOS* @param img 上传的图片文件* @return 返回图片的链接路径*/String uploadImg(MultipartFile img);String deleteImg(String key) throws QiniuException;}

serviceImpl

package com.zww.service.impl;import cn.hutool.core.util.ObjUtil;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.zww.common.exception.ServiceException;
import com.zww.framework.enums.AppHttpCodeEnum;
import com.zww.framework.enums.FileTypeEnum;
import com.zww.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;/*** @author pangpi*/
@Slf4j
@Service
public class FileServiceImpl implements FileService {// @Autowired// private ApplicationContext applicationContext;@Value("${qiniu.fileUploadType}")private String fileUploadType;@Value("${qiniu.accessKey}")private String accessKey;@Value("${qiniu.secretKey}")private String secretKey;@Value("${qiniu.bucket}")private String bucket;@Value("${qiniu.domain}")private String domain;@Value("${qiniu.fileAccess}")private String fileAccess;// akey和skey在里面定义好了@Autowiredprivate Auth auth;// 地区configuration在里面通过读取application.yml初始化好了@Autowiredprivate UploadManager uploadManager;@Autowiredprivate BucketManager bucketManager;// 这个方法就是在加工唯一文件名和校验用户上传的是否是图片格式后缀例如jpg,png@Overridepublic String uploadImg(MultipartFile img) {// 判断文件类型,和文件大小// 获取原始文件名String originalFilename = img.getOriginalFilename();if (originalFilename == null) {throw new ServiceException("文件名不能为空");// throw new ServiceException(AppHttpCodeEnum.FILL_NAME_NOT_NULL.getMsg());}// 获取文件后缀String fileSuffix = getFileSuffix(originalFilename);// 判断后缀是否匹配img// if (checkImageSuffix(fileSuffix, FileTypeEnum.IMG.getFileType())) {if (checkImageSuffix(fileSuffix, "image")) {// throw new ServiceException(AppHttpCodeEnum.FILE_TYPE_ERROR.getMsg());throw new ServiceException("上传类型格式不为图片jpg,png...");}// 通过文件获取生成的文件路径// 根据日期生成路径   2022-1-15-// new一个日期格式SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-");// 通过格式器转换一个时间String datePath = sdf.format(new Date());// uuid作为文件名String uuid = UUID.randomUUID().toString().replaceAll("-", "");// 后缀和文件后缀一致int index = originalFilename.lastIndexOf(".");// test.jpg -> .jpgString fileType = originalFilename.substring(index);String filePath = datePath + uuid + fileType;// 就是从test.jpg变成了2024-9-1-uuid32142343.jpgString url = uploadOss(img, filePath);return  url;}// 传入文件名然后调接口@Overridepublic String deleteImg(String key) throws QiniuException {// 由于bucketManager注入了spring,且初始化了a,skey,和地区,所以可以直接传bucket调用// 如果有重传需求则三次重传Response response = bucketManager.delete(this.bucket, key);int retry = 0;while (response.needRetry() && retry++ < 3) {response = bucketManager.delete(this.bucket, key);}return response.statusCode == 200 ? "删除成功!" : "删除失败!";}/*** @param file     文件* @param filePath 文件路径* @return 文件访问url*/// 如果你有别的oos,那么这里会动态获取bean并且上传// OosUploadService oosUploadService = applicationContext.getBean(fileUploadType + "_oos", OosUploadService.class);// if (ObjUtil.isNotEmpty(oosUploadService)) {//     return oosUploadService.uploadOss(file, filePath);// } else {//     log.error("对象存储 {} 不存在,请联系管理员",fileUploadType);//     throw new ServiceException(AppHttpCodeEnum.SYSTEM_ERROR.getMsg());// }// 这里直接使用qiniu_oss了,上传成功后返回字符串private String uploadOss(MultipartFile file, String filePath) {// 这里的getUploadToken()是获取上传凭证,由// Access Key: 访问密钥// Secret Key: 秘密密钥 和 存储空间名 bucket所生成// 同时还设置了令牌过期时间sxpire// 这两个密钥用于身份验证和权限控制,确保只有授权的用户可以访问或操作资源// 获取文件输入流try {// 将文件转为输入流,后面流给七牛云InputStream inputStream = file.getInputStream();try {//上传ing...Response response = this.uploadManager.put(inputStream, filePath, getUploadToken(), null, null);// 如果上一步执行没问题则说明上传完毕,此时给链接前端展示即可int retry = 0;// 如果有重传需求则三次重传while (response.needRetry() && retry < 3) {response = this.uploadManager.put(inputStream, filePath, getUploadToken(), null, null);retry++;}if (response.statusCode == 200) {return fileAccess + domain + "/" + filePath;}return "上传失败";} catch (QiniuException e) {// 如果上传失败,捕获QiniuException并打印错误信息。System.err.println(e.response.toString());throw new RuntimeException(e);}} catch (IOException e) {throw new RuntimeException(e);}}/*** 获取上传凭证*/private String getUploadToken() {return this.auth.uploadToken(bucket, null, 3600, null);}/*** 输入文件名,获取文件的后缀** @param fileName 文件名* @return 文件后缀*/private String getFileSuffix(String fileName) {// 拆分文件和后缀String[] split = fileName.split("\\.");if (split.length <= 1) {throw new ServiceException(AppHttpCodeEnum.FILL_NAME_NOT_SUFFIX.getMsg());}return split[split.length - 1];}/*** 根据传入的后缀和文件类型,判断其后缀是否正常** @param imgSuffix 文件类型* @return 是否满足后缀要求*/private boolean checkImageSuffix(String imgSuffix, String fileType) {// 暂时使用set进行判断,后续有需要改为数据库动态存储不同文件类型下的文件后缀Map<String, Set<String>> fileTypeSuffixMap = new HashMap<>();// 每个文件类型存储多个后缀格式用set存放,最后放入mapSet<String> imageSuffixName = new HashSet<>();imageSuffixName.add("jpg");imageSuffixName.add("jpeg");imageSuffixName.add("jpe");imageSuffixName.add("png");imageSuffixName.add("svg");imageSuffixName.add("webp");fileTypeSuffixMap.put(FileTypeEnum.IMG.getFileType(), imageSuffixName);Set<String> excelSuffixName = new HashSet<>();excelSuffixName.add("xlsx");excelSuffixName.add("xls");fileTypeSuffixMap.put(FileTypeEnum.EXCEL.getFileType(), excelSuffixName);Set<String> htmlSuffixName = new HashSet<>();htmlSuffixName.add("html");fileTypeSuffixMap.put(FileTypeEnum.HTML.getFileType(), htmlSuffixName);Set<String> mp3SuffixName = new HashSet<>();mp3SuffixName.add("mp3");fileTypeSuffixMap.put(FileTypeEnum.MP3.getFileType(), mp3SuffixName);Set<String> lrcSuffixName = new HashSet<>();lrcSuffixName.add("lrc");fileTypeSuffixMap.put(FileTypeEnum.LRC.getFileType(), lrcSuffixName);if (ObjUtil.isEmpty(fileTypeSuffixMap.get(fileType))) {log.error("没有这样一个类型: {} 存放在类型map中", fileType);return true;}return !(fileTypeSuffixMap.get(fileType).contains(imgSuffix));}}

初始化配置类

package com.zww.framework.config;import com.google.gson.Gson;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.zww.common.exception.GlobalException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class QiniuConfig {@Value("${qiniu.accessKey}")private String accessKey;@Value("${qiniu.secretKey}")private String secretKey;@Value("${qiniu.zone}")private String zone;/*** 配置空间的存储区域*/@Beanpublic com.qiniu.storage.Configuration qiNiuConfig() {switch (zone) {case "huadong":return new com.qiniu.storage.Configuration(Zone.huadong());case "huabei":return new com.qiniu.storage.Configuration(Zone.huabei());case "huanan":return new com.qiniu.storage.Configuration(Zone.huanan());case "beimei":return new com.qiniu.storage.Configuration(Zone.beimei());default:throw new GlobalException("存储区域配置错误");}}/*** 构建一个七牛上传工具实例*/@Beanpublic UploadManager uploadManager() {return new UploadManager(qiNiuConfig());}/*** 认证信息实例*/@Beanpublic Auth auth() {return Auth.create(accessKey, secretKey);}/*** 构建七牛空间管理实例*/@Beanpublic BucketManager bucketManager() {return new BucketManager(auth(), qiNiuConfig());}@Beanpublic Gson gson() {return new Gson();}}

测试代码

将本地图片File 对象转为multipartFile 然后调用方法

package com.zww;import com.qiniu.common.QiniuException;
import com.zww.service.FileService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;@RunWith(SpringRunner.class)
@SpringBootTest
public class QiniuTest {@Autowiredprivate FileService fileService;public static MultipartFile convert(File file) throws IOException {InputStream inputStream = new FileInputStream(file);return new MockMultipartFile("file", file.getName(), "image/jpeg", inputStream);}@Testpublic void testUpload() throws IOException {File file = new File("电脑图片链接xxxxx");MultipartFile multipartFile = convert(file);String result = fileService.uploadImg(multipartFile);System.out.println("访问地址: " + result);}@Testpublic void testDelete() throws QiniuException {String result = fileService.deleteImg("helloworld");System.out.println(result);}}
使用File作为参数,不过得

image-20240831171250604

控制台输出

image-20240831171305444

当然你也可以上传其他文件类型例如视频,文本,压缩包,这里不过多赘述,原理大差不差,前端传好参数,后端参数好好填入就行,配置文件别写错

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/413519.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多线程+连接池+代理 运行一段时间线程阻塞,如何解决??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

<Rust>egui学习之小部件(四):如何在窗口中添加滚动条Scroll部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第四篇博…

今日算法:蓝桥杯基础题之“切面条”

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注&#xff01;个人知乎 从今天开始&#xff0c;一起了解算法&#xff0c;每日一题&#xff0c;从 JavScript 的技术角度进行解答&#xff0c;如果你对算法也感兴趣&#xff0c;请多多关注哦。 问题描述 一…

【深度学习与NLP】——深度卷积神经网络AlexNet

目录 一、卷积神经网络的发展历程 二、简要介绍 三、代码实现 四、缺点和过时的地方 一、卷积神经网络的发展历程 早期理论基础阶段&#xff08;20 世纪 60 年代 - 80 年代&#xff09;&#xff1a; 1968 年&#xff0c;Hubel 和 Wiesel 通过对猫视觉神经的研究&#xff0…

Hibernate 批量插入速度慢的原因和解决方法

由于业务需要一次性连续写入超过10k条以上的新数据&#xff0c;当对象超过10个成员变量以后&#xff0c;整个写入过程居然需要长达35秒&#xff0c;这个速度是不能接受的&#xff0c;故此研究了一下怎么开启Hibernate批量写入的功能。 我这边使用的是Hibernate 5.6.15 在网上…

Python 从入门到实战3(列表的简单操作)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过python小栗子来学习python基础知识语法&#xff…

C语言中的“#”和“##”

目录 开头1.什么是#?2.什么是##?3.#和##的实际应用输出变量的名字把两个符号连接成一个符号输出根据变量的表达式…… 下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。在今天&#xff0c;我们要学一下关于C语言中的#和##的一些知识。 1.什么是#? #&#xff0…

《黑神话:悟空》:30%抽成真相

《黑神话&#xff1a;悟空》自建服务器出售&#xff1f;揭秘游戏界的30%抽成真相&#xff01; 近年来&#xff0c;随着游戏行业的迅猛发展&#xff0c;游戏开发商与发行平台之间的利益分配问题逐渐成为业界关注的焦点。其中&#xff0c;《黑神话&#xff1a;悟空》作为一款备受…

JS基础之【基本数据类型与类型间的隐式显示转换】

&#x1f680; 个人简介&#xff1a;某大型国企高级前端开发工程师&#xff0c;7年研发经验&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码…

streamlit+wordcloud使用pyinstaller打包遇到的一些坑

说明 相比常规的python程序打包&#xff0c;streamlit应用打包需要额外加一层壳&#xff0c;常规app.py应用运行直接使用 python app.py就可以运行程序了&#xff0c;但streamlit应用是需要通过streamlit命令来运行 streamlit app.py所以使用常规的pyinstaller app.py打包是…

云同步的使用

云同步技术是一种在多个设备或系统之间保持数据一致性的技术&#xff0c;它通常依赖于云存储服务来实现。在Java中&#xff0c;实现云同步功能通常需要与云服务提供商的API进行交互&#xff0c;如Amazon S3、Google Cloud Storage、Microsoft Azure Blob Storage等。 以下是一个…

秋风送爽,夏意未央|VELO Prevail Revo坐垫,一骑绿动起来吧~

夏末秋初&#xff0c;当第一片落叶缓缓飘落&#xff0c;是时候骑上你的自行车&#xff0c;迎接新的季节啦。带上维乐Prevail Revo坐垫&#xff0c;因为它独树一帜地采用EVA与回收咖啡渣精制而成的轻量发泡提升了减震性能&#xff0c;可以让你的每一次骑行都充满意义。    “…

虚幻引擎(Unreal Engine)技术使得《黑神话悟空传》大火,现在重视C++的开始吃香了,JAVA,Go,Unity都不能和C++相媲美!

虚幻引擎&#xff08;Unreal Engine&#xff09;火了黑神话游戏。 往后&#xff0c;会有大批量的公司开始模仿这个赛道&#xff01; C 的虚拟引擎技术通常指的是使用 C 语言开发的游戏引擎&#xff0c;如虚幻引擎&#xff08;Unreal Engine&#xff09;等。以下是对 C 虚拟引…

【virtuoso】INV 原理图+前仿真 + 版图 + 后仿真

采用SMIC工艺&#xff0c;不同工艺版图窗口可能有差异 1. 原理图&前仿真 1.1 绘制原理图 PMOS: NMOS宽长比2&#xff1a;1 PMOS开启导通电阻大一点&#xff0c;这样设置&#xff0c;可以使得阈值电压是VDD/2 按 i&#xff0c;可以插入器件按p&#xff0c;可以放置端口 1.2…

【机器学习】聚类算法的基本概念和实例代码以及局部度量学习的概念和实例代码

引言 聚类算法在许多领域都有广泛的应用&#xff0c;例如数据挖掘、生物信息学、图像处理等。 文章目录 引言一、聚类算法1.1 K-Means算法1.2 DBSCAN算法1.3 层次聚类&#xff08;Hierarchical Clustering&#xff09;算法1.4 高斯混合模型&#xff08;Gaussian Mixture Model&…

Web自动化测试实战--博客系统

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;测试&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1.项目效果展示 2.编写web测试用例 3.自动化测试脚本开发 3.1创建空项目 引…

Web-gpt

AJAX AJAX&#xff08;Asynchronous JavaScript and XML&#xff0c;异步JavaScript和XML&#xff09;是一种用于创建动态网页应用的技术。它允许网页在不重新加载整个页面的情况下&#xff0c;异步地从服务器请求数据&#xff0c;并将这些数据更新到网页上。这提高了用户体验…

大语言模型-GLM-General Language Model Pretraining

一、背景信息&#xff1a; GLM是2020-2021年由智谱AI研究并发布的预训练语言模型。 GLM是一种基于自回归空白填充的通用预训练语言模型。 GLM 通过添加二维位置编码和允许任意顺序预测空白区域&#xff0c;改进了空白填充预训练&#xff0c;在NLU任务上超越了 BERT 和 T5。 GL…

12 对话模型微调2

1 P-Tuning P-Tuning 是在 Prompt-Tuning的基础上&#xff0c;通过新增 LSTM 或 MLP 编码模块来加速模型的收敛&#xff1b; 之前的实验也看到了使用prompt训练速度很慢&#xff0c;那么P-Tuning呢 参数占比&#xff1a; trainable params: 5,267,456 || all params: 1,308,37…

Llamaindex RAG实践

加入xtunert文档作为提示词 让大模型理解xtuner