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…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...