springboot实现七牛云的文件上传下载
一:依赖包
<dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><qiniu-java-sdk.version>7.7.0</qiniu-java-sdk.version></dependency>
二:具体实现
@RestController
@RequestMapping("/sys/oss/qiniu")
public class OssController {@Autowiredprivate OssQiNiuHelper ossQiNiuHelper;@Value("${jeecg.oss.qiniu.domain}")private String fileDomain;/*** 七牛云文件上传** @param file 文件* @return*/@PostMapping(value = "/upload")public Result<?> upload(MultipartFile file) {if (file == null) {return Result.error("上传文件不能为空");}try {FileInputStream fileInputStream = (FileInputStream) file.getInputStream();String originalFilename = file.getOriginalFilename();String fileExtend = originalFilename.substring(originalFilename.lastIndexOf("."));String yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//默认不指定key的情况下,以文件内容的hash值作为文件名String fileKey = UUID.randomUUID().toString().substring(0,16).replace("-", "") + "-" + yyyyMMddHHmmss + fileExtend;Map<String, Object> map = new HashMap<>();DefaultPutRet uploadInfo = ossQiNiuHelper.upload(fileInputStream, fileKey);map.put("fileName", uploadInfo.key);map.put("name", originalFilename);map.put("size", file.getSize());//七牛云文件私有下载地址(看自己七牛云公开还是私有配置)map.put("url", "http://" + fileDomain + "/" + uploadInfo.key);return Result.ok(map);} catch (Exception e) {e.printStackTrace();return Result.error(e.getMessage());}}/*** 七牛云私有文件下载** @param filename 文件名* @return*/@GetMapping(value = "/private/file/{filename}")public void privateDownload(@PathVariable("filename") String filename, HttpServletResponse response) {if (filename.isEmpty()) {return;}try {String privateFile = ossQiNiuHelper.getPrivateFile(filename);response.sendRedirect(privateFile);} catch (Exception e) {e.printStackTrace();}}/*** 七牛云文件下载** @param filename 文件名* @return*/@RequestMapping(value = "/file/{filename}", method = {RequestMethod.GET})public void download(@PathVariable("filename") String filename, HttpServletResponse response) {if (filename.isEmpty()) {return;}try {String privateFile = ossQiNiuHelper.getFile(filename);response.sendRedirect("http://" + privateFile);} catch (Exception e) {e.printStackTrace();}}/*** 七牛云文件下载** @param filename 文件名* @return*/@RequestMapping(value = "/file/delete/{filename}", method = {RequestMethod.GET})public Result<?> delete(@PathVariable("filename") String filename, HttpServletResponse response) {if (filename.isEmpty()) {return Result.error("文件不能为空");}try {boolean delete = ossQiNiuHelper.delete(filename);} catch (Exception e) {e.printStackTrace();}return Result.ok("文件删除成功");}
}
三:配置类
@Configuration
public class QiNiuConfig {@Value(value = "${jeecg.oss.qiniu.accessKey}")private String accessKey;@Value(value = "${jeecg.oss.qiniu.secretKey}")private String secretKey;@Value(value = "${jeecg.oss.qiniu.zone}")private String zone;/*** 初始化配置*/@Beanpublic com.qiniu.storage.Configuration ossConfig() {System.out.println(zone);switch (zone) {case "huadong":return new com.qiniu.storage.Configuration(Region.huadong());case "huabei":return new com.qiniu.storage.Configuration(Region.huabei());case "huanan":return new com.qiniu.storage.Configuration(Region.huanan());case "beimei":return new com.qiniu.storage.Configuration(Region.beimei());default:throw new RuntimeException("存储区域配置错误");}}/*** 认证信息实例** @return*/@Beanpublic Auth auth() {return Auth.create(accessKey, secretKey);}/*** 构建一个七牛上传工具实例*/@Beanpublic UploadManager uploadManager(com.qiniu.storage.Configuration configuration) {return new UploadManager(configuration);}/*** 构建七牛空间管理实例** @param auth 认证信息* @param configuration com.qiniu.storage.Configuration* @return*/@Beanpublic BucketManager bucketManager(Auth auth, com.qiniu.storage.Configuration configuration) {return new BucketManager(auth, configuration);}/*** Gson** @return*/@Beanpublic Gson gson() {return new Gson();}
}
@Component
public class OssQiNiuHelper {@Value("${jeecg.oss.qiniu.bucketName}")private String bucketName;@Value("${jeecg.oss.qiniu.domain}")private String fileDomain;@Autowiredprivate Configuration configuration;@Autowiredprivate UploadManager uploadManager;@Autowiredprivate BucketManager bucketManager;// 密钥配置@Autowiredprivate Auth auth;@Autowiredprivate Gson gson;//简单上传模式的凭证public String getUpToken() {return auth.uploadToken(bucketName);}//覆盖上传模式的凭证public String getUpToken(String fileKey) {return auth.uploadToken(bucketName, fileKey);}/*** 上传二进制数据** @param data* @param fileKey* @return* @throws IOException*/public DefaultPutRet upload(byte[] data, String fileKey) throws IOException {Response res = uploadManager.put(data, fileKey, getUpToken(fileKey));// 解析上传成功的结果DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);return putRet;}/*** 上传输入流** @param inputStream* @param fileKey* @return* @throws IOException*/public DefaultPutRet upload(InputStream inputStream, String fileKey) throws IOException {Response res = uploadManager.put(inputStream, fileKey, getUpToken(fileKey), null, null);// 解析上传成功的结果DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);return putRet;}/*** 删除文件** @param fileKey* @return* @throws QiniuException*/public boolean delete(String fileKey) throws QiniuException {Response response = bucketManager.delete(bucketName, fileKey);return response.statusCode == 200 ? true : false;}/*** 获取公共空间文件** @param fileKey* @return*/public String getFile(String fileKey) throws Exception {String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");String url = String.format("%s/%s", fileDomain, encodedFileName);return url;}/*** 获取私有空间文件** @param fileKey* @return*/public String getPrivateFile(String fileKey) throws Exception {String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");String publicUrl = String.format("%s/%s", "http://" + fileDomain, encodedFileName);long expireInSeconds = 3600;//1小时,可以自定义链接过期时间String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);return finalUrl;}}
四:注意点
4.1.域名备案
使用七牛云的使用必须得备案域名,并且做dns解析,才能用七牛云的加速域名,七牛云默认是有几种解析方式的这里推荐使用dns解析,还有一种文件解析是比较麻烦的不推荐
4.2配置七牛云域名,一般是使用二级域名即可
配置完了二级域名去对应的域名提供服务商解析下记录即可生效
相关文章:
springboot实现七牛云的文件上传下载
一:依赖包 <dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><qiniu-java-sdk.version>7.7.0</qiniu-java-sdk.version></dependency>二:具体实现 RestController RequestMapping…...
【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(六)- 向量内存一致性模型
1. 引言 以下是《riscv-v-spec-1.0.pdf》文档的关键内容: 这是一份关于向量扩展的详细技术文档,内容覆盖了向量指令集的多个关键方面,如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量…...

Lvgl9 WindowsSimulator Visual Studio2017
因为在操作过程中遇到了一些错误,所以将操作及解决问题的过程记录下来。 一、下载lv_port_pc_visual_studio github链接:GitHub - lvgl/lv_port_pc_visual_studio: Visual Studio projects for LVGL embedded graphics library. Recommended on Windows. Linux su…...
【STL】链表(list)
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个…...
node.js常用指令
1、node:启动 Node.js REPL(交互式解释器)。 node 2、node [文件名]:执行指定的 JavaScript 文件。 node app.js 3、npm init:初始化一个新的 Node.js 项目,生成 package.json 文件。 此命令会创建一个…...

Flutter第六弹 基础列表ListView
目标: 1)Flutter有哪些常用的列表组建 2)怎么定制列表项Item? 一、ListView简介 使用标准的 ListView 构造方法非常适合只有少量数据的列表。我们还将使用内置的 ListTile widget 来给我们的条目提供可视化结构。ListView支持…...

【考研经验贴】24考研860软件工程佛系上岸经验分享【丰富简历、初复试攻略、导师志愿、资料汇总】
😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本文讲解24考研860软件工程佛系上岸经验分享【丰富简历、初复试攻略、导师志愿、资料汇总】,期待与你一同探索、学习、进步,一起卷起来叭! 目…...

15-1-Flex布局
个人主页:学习前端的小z 个人专栏:HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! 文章目录 Flex布局1 Flex容器和Flex项目2 Flex 容器属性2.1 主轴的方向2.2 主轴对齐方式…...
深入浅出 -- 系统架构之负载均衡Nginx的性能优化
一、Nginx性能优化 到这里文章的篇幅较长了,最后再来聊一下关于Nginx的性能优化,主要就简单说说收益最高的几个优化项,在这块就不再展开叙述了,毕竟影响性能都有多方面原因导致的,比如网络、服务器硬件、操作系统、后端…...

AI大模型下的策略模式与模板方法模式对比解析
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自热榜文章:设计模式深度解析:AI大模型下…...

前端| 富文本显示不全的解决方法
背景 前置条件:编辑器wangEditor vue项目 在pc端进行了富文本操作, 将word内容复制到编辑器中, 进行发布, pc端正常, 在手机端展示的时候 显示不全 分析 根据h5端编辑器内容的数据展示, 看到有一些样式造…...

数据结构——链表
目录 一、链表 1、单向链表 单向链表的遍历方式: 2、循环链表 3、双向链表 二、自行车停放(双向链表) 一、链表 链表是由许多相同数据类型的数据项按特定顺序排列而成的线性表特性:存放的位置是不连续且随机的,动…...
uniapp使用vuex
1、uniapp中使用vuex_uniapp使用vuex-CSDN博客 2、uniapp中使用vuex(store)模块的例子 - 简书 (jianshu.com) 3、vuex介绍及使用指南(面向实战)_vuex 实战应用-CSDN博客...

C++从入门到精通——this指针
this指针 前言一、this指针的引出问题 二、this指针的特性三、例题什么时候会出现编译报错什么时候会出现运行崩溃this指针存在哪里this指针可以为空吗 四、C语言和C实现Stack的对比C语言实现C实现 前言 this指针是一个特殊的指针,在C类的成员函数中使用。它指向调…...

Hive3.0.0建库表命令测试
Hive创建表格格式如下: create [external] table [if not exists] table_name [(col_name data_type [comment col_comment],)] [comment table_comment] [partitioned by(col_name data_type [comment col_comment],)] [clustered by (col_name,col_name,...)…...

一起学习python——基础篇(7)
今天讲一下python的函数。 函数是什么?函数是一段独立的代码块,这块代码是为了实现一些功能,而这个代码块只有在被调用时才能运行。 在 Python 中,使用 def 关键字定义函数: 函数的固定结构就是 def(关键字)函数名字…...

【LeetCode热题100】74. 搜索二维矩阵(二分)
一.题目要求 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,…...
Android OkHttp
目录 1.build.gradle 2.基本使用 3.POST请求 4.Builder构建者 1.build.gradle implementation("com.squareup.okhttp3:okhttp:4.12.0") 2.基本使用 GET同步请求 public void getSync(View view) {new Thread(){Overridepublic void run() {Request request …...

Java常用API_正则表达式_字符串的替换和截取方法——小练习
我将通过一个练习题来展示这两个方法 练习题: 有一段字符串:小张qwertyuiop123小李asdfghjkl456小王 要求1:把字符串中三个姓名之间的字母替换成vs 要求2:把字符串中的三个姓名切割出来 编写代码: public class Tes…...

从头开发一个RISC-V的操作系统(四)嵌入式开发介绍
文章目录 前提嵌入式开发交叉编译GDB调试,QEMU,MAKEFILE练习 目标:通过这一个系列课程的学习,开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提 这个系列的大部分文章和知识来自于:[完结] 循序渐进&#x…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...