文件上传和下载
要想实现文件上传和下载,其实只需要下述代码即可:
文件上传和下载
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.Result;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;/*** 文件上传下载接口*/
@RestController
@RequestMapping("/files")
public class FileController {// 文件上传存储路径private static final String filePath = System.getProperty("user.dir") + "/file/";/*** 文件上传** @param file 待上传的文件* @return 返回上传文件的标识符*/@PostMapping("/upload")public Result upload(MultipartFile file) {synchronized (FileController.class) {// 生成唯一标识符,避免文件覆盖String flag = System.currentTimeMillis() + ""; //当前时间戳String fileName = file.getOriginalFilename(); //文件原始名称try {// 确保文件存储目录存在if (!FileUtil.isDirectory(filePath)) {FileUtil.mkdir(filePath);}// 文件存储形式:时间戳-文件名FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName);System.out.println(fileName + "--上传成功");Thread.sleep(1L);} catch (Exception e) {System.err.println(fileName + "--文件上传失败");}// 返回文件标识符return Result.success(flag);//返回的是时间戳【数据库中存储的也是那个时间戳】相当于唯一的ID}}/*** 获取文件** @param flag 文件的标识符* @param response 用于返回文件流*/@GetMapping("/{flag}") //根据时间戳public void avatarPath(@PathVariable String flag, HttpServletResponse response) {// 确保文件存储目录存在if (!FileUtil.isDirectory(filePath)) {FileUtil.mkdir(filePath);}OutputStream os;List<String> fileNames = FileUtil.listFileNames(filePath);// 根据标识符查找对应的文件名String avatar = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");try {if (StrUtil.isNotEmpty(avatar)) {// 设置返回的文件名response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(avatar, "UTF-8"));response.setContentType("application/octet-stream");// 读取文件内容并返回byte[] bytes = FileUtil.readBytes(filePath + avatar);os = response.getOutputStream();os.write(bytes);os.flush();os.close();}} catch (Exception e) {System.out.println("文件下载失败");}}}
上述代码,算是固定写法!!可以用来上传图片,文件等资源!
拿走不谢!!
只用来看文件上传下载其实没啥意思!小编是在图书信息管理的基础上来进行图片封面的上传的!
相关代码:
图书信息管理的增删改查
- 创建数据库表
CREATE TABLE `book` (`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书名称',`price` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书价格',`author` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书作者',`press` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书出版社',`img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书封面',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- 创建实体类Book.java
@Table(name = "book")
public class Book {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(name = "name")private String name;@Column(name = "price")private String price;@Column(name = "author")private String author;@Column(name = "press")private String press;@Column(name = "img")private String img;
}
- BookDao.java BookMapper.xml
import com.example.entity.Book;
import com.example.entity.Params;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;import java.util.List;@Repository
public interface BookDao extends Mapper<Book> {List<Book> findBySearch(@Param("params") Params params);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.dao.BookDao"><select id="findBySearch" resultType="com.example.entity.Book">select * from book<where><if test="params != null and params.name != null and params.name != ''">and name like concat('%', #{ params.name }, '%')</if><if test="params != null and params.author != null and params.author != ''">and author like concat('%', #{ params.author }, '%')</if></where></select></mapper>
- BookService.java
import com.example.dao.BookDao;
import com.example.entity.Book;
import com.example.entity.Params;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;@Service
public class BookService {@Resourceprivate BookDao bookDao;public PageInfo<Book> findBySearch(Params params) {// 开启分页查询PageHelper.startPage(params.getPageNum(), params.getPageSize());// 接下来的查询会自动按照当前开启的分页设置来查询List<Book> list = bookDao.findBySearch(params);return PageInfo.of(list);}public void add(Book book) {bookDao.insertSelective(book);}public void update(Book book) {bookDao.updateByPrimaryKeySelective(book);}public void delete(Integer id) {bookDao.deleteByPrimaryKey(id);}
}
- BookController.java
import com.example.common.Result;
import com.example.entity.Book;
import com.example.entity.Params;
import com.example.service.BookService;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@CrossOrigin
@RestController
@RequestMapping("/book")
public class BookController {@Resourceprivate BookService bookService;@GetMapping("/search")public Result findBySearch(Params params) {PageInfo<Book> info = bookService.findBySearch(params);return Result.success(info);}@PostMappingpublic Result save(@RequestBody Book book) {if (book.getId() == null) {bookService.add(book);} else {bookService.update(book);}return Result.success();}@DeleteMapping("/{id}")public Result delete(@PathVariable Integer id) {bookService.delete(id);return Result.success();}}
图书封面文件上传
- FileController.java

- 上传下载接口不能拦截,需要放行
jwt令牌拦截器那块内容
// 加自定义拦截器JwtInterceptor,设置拦截规则
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**").excludePathPatterns("/api/files/**").excludePathPatterns("/api/admin/login").excludePathPatterns("/api/admin/register");
}
- BookView.vue
el-upload:Element - The world's most popular Vue UI framework
<el-form-item label="图书封面" label-width="20%"><el-upload action="http://localhost:8080/api/files/upload" :on-success="successUpload"><el-button size="small" type="primary">点击上传</el-button></el-upload>
</el-form-item>
successUpload(res) {this.form.img = res.data;
},
图书封面预览、下载
el-image:Element - The world's most popular Vue UI framework
<el-table-column label="图书封面"><template v-slot="scope"><el-imagestyle="width: 70px; height: 70px; border-radius: 50%":src="'http://localhost:8080/api/files/' + scope.row.img":preview-src-list="['http://localhost:8080/api/files/' + scope.row.img]"></el-image></template>
</el-table-column><el-button type="primary" @click="down(scope.row.img)">下载</el-button>
down(flag) {location.href = 'http://localhost:8080/api/files/' + flag
}
恭喜你,看到了最后,浪费了你一俩分钟时间,其实下面的图书信息管理的增删改查都是废话内容,最重要的就是上面的文件上传和下载,但是你还是看下去了!感谢你的信赖!
相关文章:
文件上传和下载
要想实现文件上传和下载,其实只需要下述代码即可: 文件上传和下载 import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.example.common.Result; import org.springframework.web.bind.annotation.*; import org.sprin…...
机械学习—零基础学习日志(高数22——泰勒公式理解深化)
核心思想:函数逼近 在泰勒的年代,如果想算出e的0.001次方,这是很难计算的。那为了能计算这样的数字,可以尝试逼近的思想。 但是函数又不能所有地方都相等,那退而求其次,只要在一个极小的范围,…...
Java | Leetcode Java题解之第318题最大单词长度乘积
题目: 题解: class Solution {public int maxProduct(String[] words) {Map<Integer, Integer> map new HashMap<Integer, Integer>();int length words.length;for (int i 0; i < length; i) {int mask 0;String word words[i];in…...
科普文:JUC系列之多线程门闩同步器Condition的使用和源码解读
一、概述 条件锁就是指在获取锁之后发现当前业务场景自己无法处理,而需要等待某个条件的出现才可以继续处理时使用的一种锁。 比如,在阻塞队列中,当队列中没有元素的时候是无法弹出一个元素的,这时候就需要阻塞在条件notEmpty上…...
Stable Diffusion绘画 | 图生图-基础使用介绍—提示词反推
按默认设置直接出图 拖入图片值图生图框中,保持默认设置,直接生成图片,出图效果如下: 因为重绘幅度0.7,所出图片与原图有差异,但整体的框架构图与颜色与原图类似。 输入关键词后出图 在正向提示词中输入…...
正点原子imx6ull-mini-Linux驱动之Linux SPI 驱动实验(22)
跟上一章一样,其实这些设备驱动,无非就是传感器对应寄存器的读写。而这个读写是建立在各种通信协议上的,比如上一章的i2c,我们做了什么呢,就是把设备注册成一个i2c平台驱动,这个i2c驱动怎么搞的呢ÿ…...
TypeScript 函数
函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为 的地方。 TypeScript为JavaScript函数添加了额外的功能&…...
C++ : namespace,输入与输出,函数重载,缺省参数
一,命名空间(namespace) 1.1命名空间的作用与定义 我们在学习c的过程中,经常会碰到命名冲突的情况。就拿我们在c语言中的一个string函数来说吧: int strncat 0; int main() {printf("%d", strncat);return 0; } 当我们运行之后&…...
目标检测 | yolov1 原理和介绍
1. 简介 论文链接:https://arxiv.org/abs/1506.02640 时间:2015年 作者:Joseph Redmon 代码参考:https://github.com/abeardear/pytorch-YOLO-v1 yolo属于one-stage算法,仅仅使用一个CNN网络直接预测不同目标的类别与…...
excel中有些以文本格式存储的数值如何批量转换为数字
一、背景 1.1 文本格式存储的数值特点 在平时工作中有时候会从别地方导出来表格,表格中有些数值是以文本格式存储的(特点:单元格的左上角有个绿色的小标)。 1.2 文本格式存储的数值在排序时不符合预期 当我们需要进行排序的时候…...
原神升级计划数据表:4个倒计时可以修改提示信息和时间,可以点击等级、命座、天赋、备注进行修改。
<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>原神倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;body {background: #0b1b2c;}}header {width: 100vw;heigh…...
YoloV10 论文翻译(Real-Time End-to-End Object Detection)
摘要 近年来,YOLO因其在计算成本与检测性能之间实现了有效平衡,已成为实时目标检测领域的主流范式。研究人员对YOLO的架构设计、优化目标、数据增强策略等方面进行了探索,并取得了显著进展。然而,YOLO对非极大值抑制࿰…...
第R1周:RNN-心脏病预测
本文为🔗365天深度学习训练营 中的学习记录博客 原作者:K同学啊 要求: 1.本地读取并加载数据。 2.了解循环神经网络(RNN)的构建过程 3.测试集accuracy到达87% 拔高: 1.测试集accuracy到达89% 我的环境&a…...
Golang | Leetcode Golang题解之第321题拼接最大数
题目: 题解: func maxSubsequence(a []int, k int) (s []int) {for i, v : range a {for len(s) > 0 && len(s)len(a)-1-i > k && v > s[len(s)-1] {s s[:len(s)-1]}if len(s) < k {s append(s, v)}}return }func lexico…...
远程连接本地虚拟机失败问题汇总
前言 因为我的 Ubuntu 虚拟机是新装的,并且应该装的是比较纯净的版本(纯净是指很多工具都尚未安装),然后在使用远程连接工具 XShell 连接时出现了很多问题,这些都是我之前没遇到过的(因为之前主要使用云服…...
WebRTC 初探
前言 项目中有局域网投屏与文件传输的需求,所以研究了一下 webRTC,这里记录一下学习过程。 WebRTC 基本流程以及概念 下面以 1 对 1 音视频实时通话案例介绍 WebRTC 的基本流程以及概念 WebRTC 中的角色 WebRTC 终端,负责音视频采集、编解码、NAT 穿…...
Python:read,readline和readlines的区别
在Python中,read(), readline(), 和 readlines() 是文件操作中常用的三个方法,它们都用于从文件中读取数据,但各自的使用方式和适用场景有所不同。 read() 方法: read(size-1) 方法用于从文件中读取指定数量的字符。如果指定了si…...
重生之我学编程
编程小白如何成为大神?大学新生的最佳入门攻略 编程已成为当代大学生的必备技能,但面对众多编程语言和学习资源,新生们常常感到迷茫。如何选择适合自己的编程语言?如何制定有效的学习计划?如何避免常见的学习陷阱&…...
如何将PostgreSQL的数据实时迁移到SelectDB?
PostgreSQL 作为一个开源且功能强大的关系型数据库管理系统,在 OLTP 系统中得到了广泛应用。很多企业利用其卓越的性能和灵活的架构,应对高并发事务、快速响应等需求。 然而对于 OLAP 场景,PostgreSQL 可能并不是最佳选择。 为了实现庞大规…...
关于c语言的const 指针
const * type A 指向的数据是常量 如上所示,运行结果如下,通过解引用的方式,改变了data的值 const type * A 位置是常量,不能修改 运行结果如下 type const * A 指针是个常量,指向的值可以改变 如上所示,…...
SlopeCraft:解锁Minecraft地图艺术创作的神器
SlopeCraft:解锁Minecraft地图艺术创作的神器 【免费下载链接】SlopeCraft Map Pixel Art Generator for Minecraft 项目地址: https://gitcode.com/gh_mirrors/sl/SlopeCraft 副标题:面向创意玩家的方块世界艺术生成工具,让照片秒变立…...
储能系统核心三部曲:BMS、EMS与PCS的协同交响
1. 储能系统的三大核心组件 第一次接触储能系统时,很多人都会被各种专业术语搞得晕头转向。其实就像交响乐团需要指挥、弦乐和管乐配合一样,一个高效的储能系统也离不开BMS、EMS和PCS这三大核心组件的协同工作。我在实际项目中见过太多因为组件间配合不当…...
GME多模态向量-Qwen2-VL-2B实操手册:日志监控、错误追踪与WebUI响应延迟分析
GME多模态向量-Qwen2-VL-2B实操手册:日志监控、错误追踪与WebUI响应延迟分析 你是不是也遇到过这种情况:部署了一个看起来很酷的AI模型服务,用起来效果不错,但一旦出问题就两眼一抹黑?日志在哪看?为什么响…...
OpenClaw技能商店:分享自定义nanobot模块开发经验
OpenClaw技能商店:分享自定义nanobot模块开发经验 1. 为什么需要自定义技能模块 去年夏天,当我第一次接触OpenClaw时,就被它的自动化能力所吸引。但很快我发现,官方提供的标准技能虽然强大,却无法完全满足我的个性化…...
跨设备滚动优化:Scroll Reverser让macOS操作效率提升80%的效率工具
跨设备滚动优化:Scroll Reverser让macOS操作效率提升80%的效率工具 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser 在当今多设备办公环境中,Mac用户常常面…...
Lenovo Legion Toolkit深度解析:5大场景硬件优化与性能调校实战指南
Lenovo Legion Toolkit深度解析:5大场景硬件优化与性能调校实战指南 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit …...
OpenClaw模型微调:基于nanobot镜像的Qwen3-4B定制
OpenClaw模型微调:基于nanobot镜像的Qwen3-4B定制 1. 为什么需要定制化OpenClaw模型 去年夏天,当我第一次尝试用OpenClaw自动处理团队周报时,发现通用模型对"技术复盘"这类专业内容的处理总差那么点意思。它会机械地罗列Git提交记…...
nlp_gte_sentence-embedding_chinese-large长文本处理技巧:分段与聚合策略
nlp_gte_sentence-embedding_chinese-large长文本处理技巧:分段与聚合策略 1. 引言 你是不是也遇到过这样的问题:手头有一篇几十页的技术报告或者学术论文,想要用nlp_gte_sentence-embedding_chinese-large模型来提取文本向量,却…...
用ESP32和VS1053模块DIY网络收音机:从硬件接线到Arduino代码调试全流程
用ESP32和VS1053打造智能网络收音机:从元器件选型到音频流调试实战 在物联网和智能硬件蓬勃发展的今天,ESP32凭借其出色的无线连接能力和丰富的外设接口,成为DIY音频项目的理想选择。本文将手把手带你完成一个功能完整的网络收音机项目&#…...
数字古籍获取:高效工具使用指南
数字古籍获取:高效工具使用指南 【免费下载链接】bookget bookget 数字古籍图书下载工具 项目地址: https://gitcode.com/gh_mirrors/bo/bookget 当你在研究清代方志时,面对图书馆网站繁琐的翻页操作和分散的资源链接,是否渴望一种能批…...
