云图库平台(五)——后端图片模块开发
目录
- 一、需求分析
- 二、库表设计
- 三、图片的处理
- 如何实现图片的上传和下载
- 创建图片的业务流程
- 如何对图片进行解析
- 四、创建并使用对象存储
- 五、后端操作对象存储
- 初始化客户端
- 通用能力类
- 文档上传
- 文件下载
一、需求分析
管理员功能:
- 图片的上传和创建:仅管理员使用,支持选择本地图片的上传,填写相关信息,比如名称、简介、标签、分类等。系统会自动解析图片的基础信息(如宽高和格式等),便于检索。
- 图片管理:管理员可以对图库内的图片资源进行管理,包括查询和删除。
- 图片修改(可以编辑信息):管理员可以对图片信息进行编辑,例如可以修改图片名称、标签、简介、分类等。
用户功能:
- 用户可以查看与搜索图片列表(主页):用户可以在主页上按关键词搜索图片,并支持按分类、标签等筛选条件分页查看图片列表。
- 查看图片详情:用户点击列表中的图片后,可进入详情页,查看图片的大图及相关信息,如名称、简介、分类、标签、其它图片信息(如宽高和格式等)
- 图片下载:用户在详情页可以点击下载图片按钮,将图片保存到本地。
二、库表设计
表名为picture,SQL设计如下:
-- 图片表
create table if not exists picture
( id bigint auto_increment comment 'id' primary key, url varchar(512) not null comment '图片 url', name varchar(128) not null comment '图片名称', introduction varchar(512) null comment '简介', category varchar(64) null comment '分类', tags varchar(512) null comment '标签(JSON 数组)', picSize bigint null comment '图片体积', picWidth int null comment '图片宽度', picHeight int null comment '图片高度', picScale double null comment '图片宽高比例', picFormat varchar(32) null comment '图片格式', userId bigint not null comment '创建用户 id', createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', editTime datetime default CURRENT_TIMESTAMP not null comment '编辑时间', updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', isDelete tinyint default 0 not null comment '是否删除', INDEX idx_name (name), -- 提升基于图片名称的查询性能 INDEX idx_introduction (introduction), -- 用于模糊搜索图片简介 INDEX idx_category (category), -- 提升基于分类的查询性能 INDEX idx_tags (tags), -- 提升基于标签的查询性能 INDEX idx_userId (userId) -- 提升基于用户 ID 的查询性能
) comment '图片' collate = utf8mb4_unicode_ci;
三、图片的处理
如何实现图片的上传和下载
使用对象存储来进行图片的存储:
- 这里使用的对象存储服务是腾讯云的COS,可以通过控制台、API、SDK等方式来快速接入COS,同时可以进行多格式文件的上传和下载。
创建图片的业务流程
创建图片主要是包括两个过程:第一个过程是上传图片文件本身,第二个过程是将图片信息上传到数据库。
有两种常见的处理方式:
- 先上传再提交数据(大多数的处理方式):用户直接上传图片,系统自动生成图片的url存储地址;然后在用户填写其它相关信息并提交后才将图片记录保存到数据库中。
- 上传图片时直接记录图片信息:云图库平台中图片作为核心资源,只要用户将图片上传成功南无就应该把这个图片上传到数据库中(即用户上传图片后系统应该立即生成图片的完整数据记录和其它元信息,这里元信息指的是图片的一些基础信息,这些信息应该是在图片上传成功后就能够解析出来),无需等待用户上传提交图片信息就会立即存入数据库中,这样会使整个交互过程更加轻量。这样的话用户只需要再上传图片的其它信息即可,这样就相当于用户对已有的图片信息进行编辑。
当然我们也可以对用户进行一些限制,比如说当用户上传过多的图片资源时就禁止该用户继续上传图片资源。
如何对图片进行解析
根据具体的需求我们还需要获取到图片的信息,比如图片的宽度、高度、宽高比、文件格式、图片大小、图片名称。
常见的图片解析方式有两种:
- 在后端服务器直接处理图片的方式:比如java库ImagelO、Python中的Pillow,或者说适用范围更加广泛的OpenCV。
- 通过第三方云存储服务的方式:比如腾讯云COS、AWS S3或者图片处理API(比如ImageMagick、ExifTool)直接提取图片的元数据。
本项目中使用腾讯云COS对象存储来实现图片资源的上传和下载,腾讯云COS对象存储支持在图片上传时通过数据万象服务直接获取到图片的各种基础信息:
四、创建并使用对象存储
前往腾讯云搜索对象存储:
点击存储桶列表:
创建存储桶:
地域一般选择要服务的用户的地域,选择公有读私有写,内容安全不要开(要需要交米);然后点击下一步即可
下面三个都不要开,服务端加密选择不加密:
然后点击下一步创建就好了。创建成功后控制台就会出现下图的内容:

创建成功后可以在控制台中上传文件:
一定要注意:对象存储不要给别人看到。接下来通过后端来操作对象存储。
五、后端操作对象存储
初始化客户端
我们需要引入依赖来操作对象存储。可以参考官方文档
<dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.6.227</version>
</dependency>

另外腾讯云提供了云API来帮助我们进行接口的测试,比如说获取文件、查看文件的信息等等.

现在我们参照官方文档来初始化客户端。
-
要注意防止密码泄露,所以新建
application-local.yml文件,并且在.gitignore文件中忽略该文件的提交,这样就不会将代码等敏感配置提交到代码仓库中去了。 -
填写配置文件:新建
application-local.yml文件,并在.gitignore中忽略该文件的提交,这样就不会将代码等敏感配置提交到代码仓库。application-local.yml文件配置如下:
# 对象存储配置(需要从腾讯云获取)
cos: client: host: xxx secretId: xxx secretKey: xxx region: xxx bucket: xxx
-
选择更改配置:


-
在项目的
config包下新建CosClientConfig类。负责读取配置文件,代码如下:
@Configuration
@ConfigurationProperties(prefix = "cos.client")
@Data
public class CosClientConfig { /** * 域名 */ private String host; /** * secretId */ private String secretId; /** * 密钥(注意不要泄露) */ private String secretKey; /** * 区域 */ private String region; /** * 桶名 */ private String bucket; @Bean public COSClient cosClient() { // 初始化用户身份信息(secretId, secretKey) COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); // 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224 ClientConfig clientConfig = new ClientConfig(new Region(region)); // 生成cos客户端 return new COSClient(cred, clientConfig); }
}
通用能力类
新建manager包(一般指可以复用的代码,我们也可以将manager包复制到别的项目中):
- 在该包下新建
CosManager类提供通用的对象存储操作(比如文件上传和下载),该类需要引入对象存储配置和COS客户端,用于和COS进行交互,代码如下:
@Component
public class CosManager { @Resource private CosClientConfig cosClientConfig; @Resource private COSClient cosClient; // ... 一些操作 COS 的方法
}
接下来就是编写文档上传和下载的方法。
文档上传
这里可以参考官方文档部分,在CosManagert中新增上传对象的方法,代码如下:
/** * 上传对象 * * @param key 唯一键 * @param file 文件 */
public PutObjectResult putObject(String key, File file) { PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, file); return cosClient.putObject(putObjectRequest);
}
接下来我们在controller包中新建FileController来编写测试文件上传接口。核心流程是先接受用户上传的文件,指定上传的路径,然后调用cosManager.putObject方法上传文件到 COS 对象存储;上传成功后,会返回一个文件的 key(其实就是文件路径),便于我们访问和下载文件。注意:测试接口一定要加上管理员权限,防止任何用户随意上传文件。
测试文件上传接口代码如下:
/** * 测试文件上传 * * @param multipartFile * @return */
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
@PostMapping("/test/upload")
public BaseResponse<String> testUploadFile(@RequestPart("file") MultipartFile multipartFile) { // 文件目录 String filename = multipartFile.getOriginalFilename(); String filepath = String.format("/test/%s", filename); File file = null; try { // 上传文件 file = File.createTempFile(filepath, null); multipartFile.transferTo(file); cosManager.putObject(filepath, file); // 返回可访问地址 return ResultUtils.success(filepath); } catch (Exception e) { log.error("file upload error, filepath = " + filepath, e); throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败"); } finally { if (file != null) { // 删除临时文件 boolean delete = file.delete(); if (!delete) { log.error("file delete error, filepath = {}", filepath); } } }
}
下面进行接口测试,使用
local配置启动项目,如下图:
除了这种方法外,也可以在主配置文件中指定激活的环境配置。
spring: profiles: active: local
然后使用Swagger接口文档进行测试(上传之前不要忘记登录)
文件下载
有好几种文件下载方式,由于项目中的图片是公开的,所以我们直接通过URL路径链接访问,适用于单一的,可以被用户公开访问的资源。
(1)在CosManager类中新增对象下载方法,根据对象的key获取存储信息:
/** * 下载对象 * * @param key 唯一键 */
public COSObject getObject(String key) { GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key); return cosClient.getObject(getObjectRequest);
}
(2)在FileController中编写测试文件下载接口。
核心流程是根据路径获取到COS文件对象,然后将文件对象转换为文件流,并写入到Servlet的 Response对象中。注意要设置文件下载专属的响应头。测试接口一定要加上管理员权限!防止任何用户随意上传文件。
测试文件下载接口代码如下:
/** * 测试文件下载 * * @param filepath 文件路径 * @param response 响应对象 */
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
@GetMapping("/test/download/")
public void testDownloadFile(String filepath, HttpServletResponse response) throws IOException { COSObjectInputStream cosObjectInput = null; try { COSObject cosObject = cosManager.getObject(filepath); cosObjectInput = cosObject.getObjectContent(); // 处理下载到的流 byte[] bytes = IOUtils.toByteArray(cosObjectInput); // 设置响应头 response.setContentType("application/octet-stream;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + filepath); // 写入响应 response.getOutputStream().write(bytes); response.getOutputStream().flush(); } catch (Exception e) { log.error("file download error, filepath = " + filepath, e); throw new BusinessException(ErrorCode.SYSTEM_ERROR, "下载失败"); } finally { if (cosObjectInput != null) { cosObjectInput.close(); } }
}
(3)启动项目,打开Swagger接口文档,测试文件下载:

到这里,通用的文件上传下载的代码已经完成。在其它项目中,我们完全可以直接使用CosManager中的代码
相关文章:
云图库平台(五)——后端图片模块开发
目录 一、需求分析二、库表设计三、图片的处理如何实现图片的上传和下载创建图片的业务流程如何对图片进行解析 四、创建并使用对象存储五、后端操作对象存储初始化客户端通用能力类文档上传文件下载 一、需求分析 管理员功能: 图片的上传和创建:仅管理…...
postman调用ollama的api
按照如下设置,不需要设置key 保持长会话的方法 # 首次请求 curl http://localhost:11434/api/generate -d {"model": "deepseek-r1:32b","prompt": "请永久记住:110,1-12,之后所有数学计算必…...
十、OSG学习笔记-多线程(OpenThreads)
上一节内容: 九、OSG学习笔记-NodeVisitor节点遍历器-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145742756?spm1001.2014.3001.5501 本章节代码: OsgStudy/Openthreads CuiQingCheng/OsgStudy - 码云 - 开源中国https://gite…...
Gemma 2 的滑动窗口注意力(Sliding Window Attention)解析:源代码
Gemma 2 的滑动窗口注意力(Sliding Window Attention)解析 在 Transformer 结构 中,自注意力(Self-Attention)是核心机制之一。然而,标准的自注意力计算复杂度为 ( O ( n 2 ) O(n^2) O(n2) ),随…...
机器学习数学通关指南——链式法则
前言 本文隶属于专栏《机器学习数学通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 一、定义与公式 链式法则&a…...
Python爬虫实战:从零到一构建数据采集系统
文章目录 前言一、准备工作1.1 环境配置1.2 选择目标网站 二、爬虫实现步骤2.1 获取网页内容2.2 解析HTML2.3 数据保存 三、完整代码示例四、优化与扩展4.1 反爬应对策略4.2 动态页面处理4.3 数据可视化扩展 五、注意事项六、总结互动环节 前言 在大数据时代,数据采…...
DeepSeek 助力 Vue 开发:打造丝滑的单选按钮(Radio Button)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
【行业解决方案篇十八】【DeepSeek航空航天:故障诊断专家系统 】
引言:为什么说这是“航天故障终结者”? 2025年春节刚过,航天宏图突然官宣"DeepSeek已在天权智能体上线",这个搭载在卫星和空间站上的神秘系统,号称能提前48小时预判99.97%的航天器故障。这不禁让人想起年初NASA禁用DeepSeek引发的轩然大波,更让人好奇:这套系…...
谷歌浏览器更新后导致的刷新数据无法显示
这几天突然出现的问题,就是我做了一个网站,一直用Google展示,前两天突然就是刷新会丢失数据,然后再刷新几次吧又有了,之前一直好好的,后端也做了一些配置添加了CrossOrigin注解,然而换了edge浏览…...
nvidia-docker2 和 NVIDIA Container Toolkit 的区别及推荐
NVIDIA Docker 和 NVIDIA Container Toolkit 1. NVIDIA Docker 和 NVIDIA Docker2 nvidia-docker 是 NVIDIA 最早推出的工具,用于在 Docker 容器中启用 GPU 支持。它以独立守护进程的形式作为 Volume Plugin 存在,但与 Docker 生态系统的兼容性较差&am…...
游戏设计模式阅读 - 游戏循环
游戏与普通程序最大的不同点在于: 游戏不像其他大多数软件,游戏即使在没有玩家输入时也继续运行。 如果你站在那里看着屏幕,游戏也不会冻结。动画会持续播放。视觉效果继续闪烁。 如果运气不好的话,怪物会继续暴揍你的角色。 那么…...
(五)趣学设计模式 之 建造者模式!
目录 一、 啥是建造者模式?二、 为什么要用建造者模式?三、 建造者模式怎么实现?四、 建造者模式的应用场景五、 建造者模式的优点和缺点六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方…...
github 怎么创建一个私有repository 并从另外一台电脑拉取下来更新
1.github上新建一个repository 设置为private tips删除在这 点setting 然后往下拖动 会有个这里是用来删项目的 2.另外 一台电脑拉取这个repository的时候 需要配置 一个ssh key 这个key的内容生成参考本地电脑的生成 然后在这配置 2.1 生成 SSH 密钥(如果还没有…...
Spring Boot嵌入式服务器深度解析:从配置到调优的全方位指南
文章目录 引言一、嵌入式服务器核心原理1.1 架构设计特点1.2 主流服务器对比 二、嵌入式服务器配置实战2.1 基础配置模板2.2 HTTPS安全配置 三、高级调优策略3.1 线程池优化(Tomcat示例)3.2 响应压缩配置3.3 访问日志配置 四、服务器切换实战4.1 切换至U…...
DeepSeek-R1本地化部署的硬件要求
DeepSeek-R1本地化部署的硬件要求全解析 引言 DeepSeek-R1作为一款高效的AI推理模型,凭借其卓越的推理性能和灵活的训练机制,成为了春节期间的热议话题。 然而,要在本地成功部署DeepSeek-R1,尤其是其满载的 671B 参数版本&#…...
AGI觉醒假说的科学反驳:从数学根基到现实约束的深度解析
文章目录 引言:AGI觉醒论的核心迷思一、信息论视角:意识产生的熵约束1.1 香农熵的物理极限1.2 量子退相干的时间屏障二、数学根基:形式系统的自指困境2.1 哥德尔不完备定理的现代诠释三、概念解构:AGI觉醒假说的认知陷阱3.1 术语混淆的迷雾3.2 拟人化谬误的认知根源四、意识…...
CSS—盒模型(3分钟结合示例精通盒模型)
个人博客:haichenyi.com。感谢关注 1. 目录 1–目录2–概念3–内容4–内边距5–边框6–外边距7–类型 概念 在HTML中,每一个元素都可以看作一个矩形的盒子。如图 如上图所示,一个一个的矩形都可以堪称一个元素。矩形有大有小,边有…...
蓝桥杯 3.搜索
蓝桥杯 3.搜索 文章目录 蓝桥杯 3.搜索DFS回溯DFS剪枝记忆化搜索编程66-75 DFS回溯 回溯法简介 使用**DFS(深度优先搜索)**实现, DFS是一种遍历或搜索图, 树或者图像等数据结构的算法, 当然这个图, 树未必要存储下来(隐式处理就是回溯法)搜索树一般是排列型搜索树 (总节点个数…...
JQD武学思想
无意识,无我,空,无形, 刚柔相济,时机, 战胜对手,克服内心。不预测结果,自发反击。 简单直接的攻击,去除一切冗余的东西。 李小龙其实反复在解释这些概念,常…...
供应链管理-谈判:分配式谈判、整合式谈判、原则式谈判
一、分配式谈判 序号要点解释1特点双方在一定资源或利益范围内进行分配,一方所得即另一方所失,因此也被称为“零和谈判”。2适用场景资源有限、关系不是关键因素,以及需要快速决策的情况。例如,在竞争对手之间,如拍卖…...
C语言递归——青蛙跳台阶问题和汉诺塔问题
一、青蛙跳台阶问题 •题目描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上n级台阶总共有多少种跳法。 •问题分析: 青蛙跳台阶问题可以分成n个子问题。假设青蛙要跳上n级台阶,那么它的最后一步有两种选择&…...
relief=tk.RAISED详细介绍 relief是指定控件的边框样式
relieftk.RAISED 是在使用 Python 的 Tkinter 库创建图形用户界面(GUI)时,用于设置控件外观样式的一个参数设置,下面为你详细解释: 整体功能概述 在 Tkinter 里,relief 参数用于指定控件的边框样式&#x…...
基于ffmpeg+openGL ES实现的视频编辑工具-添加转场(九)
在视频编辑的广阔领域中,转场效果无疑是提升视频流畅性与观赏性的关键要素。巧妙运用转场,能够让不同视频片段之间的衔接更为自然,同时赋予视频独特的创意魅力。本文将深入探讨如何借助 ffmpeg 和 openGL ES 技术,在视频编辑工具中实现丰富多样的转场效果。 一、转场技术原…...
2025.2.21 日校内模拟赛总结(AC自动机, 期望,倍增)
文章目录 时间安排题解 时间安排 将近两个半小时才过 T 1 T1 T1,后面花一个半小时过了 T 2 T2 T2,最后半个小时写不出 T 3 T3 T3 暴力没有获得分数。 反思: T 1 T1 T1 这种题要敢于去猜结论打表,由于没有直接猜结论做了很长时…...
STM32的“Unique device ID“能否修改?
STM32F1系列的"Unique device ID"寄存器的地址为0x1FFFF7E8。 这个寄存器是只读的。 "Unique device ID"寄存器位于“System memory”中。“System memory”地址范围为“0x1FFF F000- 0x1FFF F7FF”。 所有STM32 MCU上都存在系统引导加载程序。顾名思义&a…...
[内网基础] 内网基础知识 —— Windows 工作组
关注这个专栏的其他相关笔记:[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01:Windows 工作组介绍 在一个大型单位里,可能有成百上千台计算机互相连接组成局域网,如果不对这些计算机进行分组,网络的混乱程度是可想而知…...
【新手初学】SQL注入之二次注入、中转注入、伪静态注入
二次注入 一、概念 二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。 二、原理 防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处…...
Deepseek存算分离安全部署手册
Deepseek大火后,很多文章教大家部署Dfiy和ollamadeepseek,但是大部分都忽略了数据安全问题,本文重点介绍Deepseek存算分裂安全架设,GPU云主机只负责计算、CPU本地主机负责数据存储,确保数据不上云,保证私有…...
单页图床HTML源码+本地API接口图床系统修复版源码
源码介绍 图床系统是一种用于存储和管理图片文件的在线服务。它允许用户上传图片文件,并生成相应的图片链接,从而方便用户在网页、社交媒体或其他平台上分享图片。 PS:源码压缩包分为两个版本,一个是调用360第三方api接口,另外一…...
XML DOM4J 三、XPath
1 什么是XPath XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初 XPath 的提出的初衷是将其作为一个通用的、介于XPointe…...










