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…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
World-writable config file /etc/mysql/mysql.conf.d/my.cnf is ignored
https://stackoverflow.com/questions/53741107/mysql-in-docker-on-ubuntu-warning-world-writable-config-file-is-ignored 修改权限 -> 重启mysql # 检查字符集配置 SHOW VARIABLES WHERE Variable_name IN (character_set_server, character_set_database ); --------…...
