SpringMVC之文件上传下载以及jrebel的使用
目录
一、文件上传
1.1 导入依赖
1.2 配置文件上传解析器
1.3 配置服务器存放文件地址
1.3.1 点击编辑Configurations
1.3.2 将项目部署至tomcat服务器上
1.3.3 配置相对路径
1.4 导入PropertiesUtil工具类
1.5 编写resource.properties
1.6 添加sql
1.7 编写PageController类
1.8 编写主页展示界面
1.9 编写文件上传方法
1.10 搭建一个图片上传的操作页面
二、文件下载
三、多文件上传
四、jrebel的使用
4.1 jrebel插件的安装
4.2 打开代理
4.3 设置jrebel离线
五、收获
一、文件上传
演示代码基于上篇博客:SpringMVC之CRUD
https://blog.csdn.net/weixin_74263417/article/details/132763882?spm=1001.2014.3001.5501
我这里的属性名为jay_music数据表的字段如图 :

由于我们在上篇已经生成了带图片属性的接口、实体以及配置文件。所以我们就不需要重新逆向生成mapper和model包中的代码了。
1.1 导入依赖
导入依赖:
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version>
</dependency>
1.2 配置文件上传解析器
在spring-mvc.xml中配置文件上传解析器,代码如下:
<!-- 处理文件上传下载问题--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 --><property name="defaultEncoding" value="UTF-8"></property><!-- 文件最大大小(字节) 1024*1024*50=50M--><property name="maxUploadSize" value="52428800"></property><!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常--><property name="resolveLazily" value="true"/></bean>
CommonsMultipartResolver是MultipartResolver接口的实现类。
1.3 配置服务器存放文件地址
具体操作如下:
1.3.1 点击编辑Configurations

1.3.2 将项目部署至tomcat服务器上

1.3.3 配置相对路径

注:本地路径名需与resource.properties资源文件中路径保持一致。

然后保存好即可。
1.4 导入PropertiesUtil工具类
package com.Kissship.utils;import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;public class PropertiesUtil {public static String getValue(String key) throws IOException {Properties p = new Properties();InputStream in = PropertiesUtil.class.getResourceAsStream("/resource.properties");p.load(in);return p.getProperty(key);}}
1.5 编写resource.properties
创建一个名为resource.properties的资源文件,如下:
dir=D:/temp/upload/
server=/upload/
dir作为上传图片的真实地址,而server即是网络访问地址。
1.6 添加sql
在逆向生成后的musicmapper.xml中加入以下代码:
<select id="listPager" resultType="com.Kissship.model.Music" parameterType="com.Kissship.model.Music" >select*from jay_music<where><if test="mname != null">and mname like concat('%',#{mname},'%')</if></where></select>
紧接着在自动生成的mapper类中加入以下代码:
List<Music> listPager(Music music);
1.7 编写PageController类
然后再创建一个公共路径处理类 PageController类,代码如下:
package com.Kissship.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;/*** @author Kissship* @site www.Kissship.com* @company xxx公司* @create 2023-09-07-15:01** 用来处理页面跳转*/
@Controller
public class PageController {//<a href="order/preSave">新增</a> 新增界面@RequestMapping("/page/{page}")public String toPage(@PathVariable("page") String page){return page;}@RequestMapping("/page/{dir}/{page}")public String toDirPage(@PathVariable("dir") String dir,@PathVariable("page") String page){return dir + "/" + page;}}
1.8 编写主页展示界面
主页代码 list.jsp如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib uri="http://jsp.veryedu.cn" prefix="z"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><linkhref="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"rel="stylesheet"><scriptsrc="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script><title>JayChou歌单列表</title><style type="text/css">.page-item input {padding: 0;width: 40px;height: 100%;text-align: center;margin: 0 6px;}.page-item input, .page-item b {line-height: 38px;float: left;font-weight: 400;}.page-item.go-input {margin: 0 10px;}</style>
</head>
<body>
<form class="form-inline"action="${pageContext.request.contextPath }/mic/list" method="post"><div class="form-group mb-2"><input type="text" class="form-control-plaintext" name="mname"placeholder="请输入歌曲名称"><!-- <input name="rows" value="20" type="hidden"> --><!-- 不想分页 -->
<%-- <input name="pagination" value="false" type="hidden">--%></div><button type="submit" class="btn btn-primary mb-2">查询</button><a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/mic/preSave">新增</a>
</form><table class="table table-striped"><thead><tr><th scope="col">歌曲编号</th><th scope="col">歌曲名称</th><th scope="col">歌曲专辑</th><th scope="col">歌曲歌词</th><th scope="col">歌曲图片</th></tr></thead><tbody><c:forEach var="b" items="${lst }"><tr><td>${b.mid }</td><td>${b.mname }</td><td>${b.mtype }</td><td>${b.minfo }</td><td><img src="${b.mpic }" style="height: 60px;width: 60px"></td><td><a href="${pageContext.request.contextPath }/mic/preSave?mid=${b.mid}">修改</a><a href="${pageContext.request.contextPath }/mic/del/${b.mid}">删除</a><a href="${pageContext.request.contextPath }/page/mic/upload?mid=${b.mid}">图片上传</a><a href="${pageContext.request.contextPath }/mic/download?mid=${b.mid}">图片下载</a></td></tr></c:forEach></tbody>
</table>
<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
<z:page pageBean="${pageBean }"></z:page>
${pageBean }
</body>
</html>
1.9 编写文件上传方法
在我们的MusicController控制器中增加文件上传的方法进行配置,要增加的代码如下:
//文件上传@RequestMapping("/upload")public String upload(Music music,MultipartFile m){try {
// 3.后端可以直接利用mutipartFile类,接受前端传递到后台的文件//上传的图片真实存放地址String dir = PropertiesUtil.getValue("dir");//网络访问地址String server = PropertiesUtil.getValue("server");String fileName = m.getOriginalFilename();System.out.println("文件名:"+fileName);System.out.println("文件类别:"+m.getContentType());//4.将文件转成流,然后写入服务器(某一个硬盘)FileUtils.copyInputStreamToFile(m.getInputStream(),new File(dir+fileName));music.setMpic(server+fileName);musicBiz.updateByPrimaryKeySelective(music);} catch (IOException e) {e.printStackTrace();}return "redirect:list";}
1.10 搭建一个图片上传的操作页面
创建一个新的upload.jsp页面作为图片上传操作页面,upload.jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>专辑图片上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/mic/upload" method="post" enctype="multipart/form-data"><label>歌曲编号:</label><input type="text" name="mid" readonly="readonly" value="${param.mid}"/><br/><label>专辑图片:</label><input type="file" name="m"/><br/><input type="submit" value="上传图片"/>
</form>
<form method="post" action="${pageContext.request.contextPath}/mic/uploads" enctype="multipart/form-data"><input type="file" name="files" multiple><button type="submit">上传</button>
</form>
</body>
</html>
然后启动tomcat服务器访问路径进行测试,测试结果如下:

二、文件下载
在Controller层中加入以下代码,如下:
//文件下载实现@RequestMapping(value="/download")public ResponseEntity<byte[]> download(Music music,HttpServletRequest req){try {//先根据文件id查询对应图片信息Music mic = this.musicBiz.selectByPrimaryKey(music.getMid());String diskPath = PropertiesUtil.getValue("dir");String reqPath = PropertiesUtil.getValue("server");String realPath = mic.getMpic().replace(reqPath,diskPath);String fileName = realPath.substring(realPath.lastIndexOf("/")+1);//下载关键代码File file=new File(realPath);HttpHeaders headers = new HttpHeaders();//http头信息String downloadFileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");//设置编码headers.setContentDispositionFormData("attachment", downloadFileName);headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//MediaType:互联网媒介类型 contentType:具体请求中的媒体类型信息return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);}catch (Exception e){e.printStackTrace();}return null;
之后重启tomcat服务器进行测试,结果如下:

三、多文件上传
多文件上传和普通文件上传的区别:
- 参数类型不同:多文件上传使用MultipartFile[]作为参数类型,而普通文件上传使用MultipartFile作为参数类型。
- 前端表单处理不同:多文件上传需要使用input[type=“file”]的multiple属性,并选择多个文件进行上传,而普通文件上传只能选择单个文件上传。
- 后端处理方式不同:多文件上传需要接收文件数组,可以对每个文件进行处理;普通文件上传只能接收单个文件。
在Controller层中加入以下代码,如下:
//多文件上传@RequestMapping("/uploads")public String uploads(HttpServletRequest req, Music music, MultipartFile[] files){try {StringBuffer sb = new StringBuffer();for (MultipartFile cfile : files) {//思路://1) 将上传图片保存到服务器中的指定位置String dir = PropertiesUtil.getValue("dir");String server = PropertiesUtil.getValue("server");String filename = cfile.getOriginalFilename();FileUtils.copyInputStreamToFile(cfile.getInputStream(),new File(dir+filename));sb.append(filename).append(",");}System.out.println(sb.toString());} catch (Exception e) {e.printStackTrace();}return "redirect:list";}
增加完后重启tomcat服务器进行测试,测试结果如下:

四、jrebel的使用
使用 JRebel 启动项目有以下好处:
快速部署:JRebel 允许在应用程序运行时热部署代码和资源文件,而无需重新启动整个应用程序。这大大提高了开发效率,省去了传统的重启应用程序的时间。
即时生效:JRebel 对于大部分代码和资源的修改,都能够实时生效,无须手动重新编译和重新部署。这使得开发人员能够立即看到他们所做的更改的效果,快速迭代开发。
保持应用状态:JRebel 可以保持应用程序的状态,包括各种已经加载的类、对象、变量等。这意味着在代码修改后,应用程序的状态仍然可以保持不变,不会丢失用户的登录状态、缓存数据等。
支持多种框架和技术栈:JRebel 不仅适用于 Java SE 和 Java EE 应用程序,还支持许多主流的框架和技术栈,如Spring、Hibernate、Maven、Gradle等。这使得 JRebel 能够应用于各种类型的项目。
减少开发周期:由于 JRebel 的快速部署和即时生效特性,开发人员可以迅速验证和修改他们的代码,减少了开发周期。这有助于提高团队的开发效率和项目的交付速度。
4.1 jrebel插件的安装


重启后的IDEA是这样的:

但是此时我们还需要打开代理(黑窗口)才可以用jrebel启动项目。如下:
4.2 打开代理
下载代理,进行jrebel的使用:
![]()
4.3 设置jrebel离线
打开代理后点击jrebel启动项目,会弹出以下窗口,具体操作如下:
1.在弹出框中Team URL下方第一个输入框输入:
http://127.0.0.1:8888/0e63ac70-2074-46d3-9de1-46fb2befde0a
2.在第二个输入框输入自己的邮箱。
3.勾选 I agree with the term...
4.最后点击最下方按钮Activete JRebel即可。
设置完jrebel离线之后,在用jrebel插件启动项目之前就可以不打开代理辅助工具了。
五、收获
学习 Spring MVC 文件上传与下载可以给我们带来以下收获:
扩展技能:掌握 Spring MVC 文件上传与下载技术,可以扩展你的技能范围。这使得你成为一个更全面的开发人员,可以处理包括文件上传与下载在内的更广泛的任务。
实现功能需求:文件上传与下载是许多 Web 应用程序常见的功能需求。通过学习 Spring MVC 文件上传与下载,你可以满足项目或产品的要求,将其集成到你的应用程序中,让用户能够上传和下载文件。
提升用户体验:文件上传与下载功能可以提升用户体验,使用户能够方便地上传所需的文件或下载所需的资源。这对于许多应用程序来说是重要的功能特性,可以提高用户的满意度和使用度。
理解文件操作原理:学习文件上传与下载的实现原理可以让你更深入地理解文件操作的相关概念和技术。你可以了解如何处理文件的输入输出、如何管理文件的存储和访问,以及如何在应用程序中保护文件的安全性。
强化项目开发能力:掌握文件上传与下载技术可以强化你的项目开发能力。你可以更好地处理文件相关的需求,比如批量文件上传、大文件上传、文件分片上传等,提高开发效率和代码质量。
解决实际问题:学习文件上传与下载技术可以帮助你解决实际的问题和挑战。你可以应对各种情况,如文件大小限制、文件类型验证、安全性控制等,确保文件操作的可靠性和稳定性。
最后SpringMVC之文件上传下载以及jrebel的使用就到这里,祝大家在敲代码的路上一路通畅!

相关文章:
SpringMVC之文件上传下载以及jrebel的使用
目录 一、文件上传 1.1 导入依赖 1.2 配置文件上传解析器 1.3 配置服务器存放文件地址 1.3.1 点击编辑Configurations 1.3.2 将项目部署至tomcat服务器上 1.3.3 配置相对路径 1.4 导入PropertiesUtil工具类 1.5 编写resource.properties 1.6 添加sql 1.7 编写PageCo…...
基于Fomantic UI Web构建 个人导航站点网站源码 网站技术导航源码
BYR-Navi-master好看有个性的网站技术导航源码 该网站基于Fomantic UI Web框架构建,整个项目的设计和构建具有高度的配置和定制灵活性。 整体风格比较适合个人导航站点使用 搜索框输入关键词后,点击上方搜索引擎图标可跳转打开对应搜索引擎搜索结果&am…...
DRF02-请求响应与路由
文章目录 1. http请求响应1.1. 请求与响应1.1.1 Request1.1.1.1 常用属性1).data2).query_params3)request._request基本使用1.1.2 Response1.1.2.1 构造方式1.1.2.2 response对象的属性1).data2).status_code3).content1.1.2.3 状态码1)信息告知 - 1xx2)成功 - 2xx3)…...
http直接调用paddlepaddle实现文字转语音,语音转文字
由于环境问题,折腾好久,记录下来,安装后使用还是很方便的 记录下来,方便自己,方便大家 1.安装 参考官方文档: mirrors / paddlepaddle / paddlespeech GitCode 2.启动server 参考官方文档: mirrors / paddlepaddle / paddlespeech GitCode 3.直接调用 参考官方文档: htt…...
9. xaml ComboBox控件
1.运行图像 2.运行源码 a.Xaml源码 <Grid Name="Grid1"><!--IsDropDownOpen="True" 默认就是打开的--><ComboBox x:Name="co...
【后量子密码】CRYSTALS-KYBER 算法(二):密钥封装 KEM(附源码分析)
一、前言 Kyber 算法是一种满足 IND-CCA2 安全的密钥封装机制(key-encapsulation mechanism,KEM),其安全性依赖于MLWE 问题的困难性。Kyber 算法构建采用了两阶段的方法:首先引入了一种IND-CPA 安全的公钥加密方案,用于加密长度为32字节的消息,称之为Kyber.CPAPKE;然后…...
什么是原⼦操作?在 JUC 中有哪些原⼦类?
原子操作是一种在多线程环境下不会被中断的操作,它要么完全执行,要么完全不执行,不会出现中间状态。原子操作通常是对共享数据的操作,确保多个线程同时访问共享数据时不会导致数据不一致或损坏。 在Java中,java.util.concurrent 包提供了一组原子类,用于执行原子操作。以…...
2022年12月 C/C++(八级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:生理周期 人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。因…...
Hadoop的HDFS的集群安装部署
注意:主机名不要有/_等特殊的字符,不然后面会出问题。有问题可以看看第5点(问题)。 1、下载 1.1、去官网,点下载 下载地址:https://hadoop.apache.org/ 1.2、选择下载的版本 1.2.1、最新版 1.2.2、其…...
uniapp 在 onLoad 事件中 this.$refs 娶不到的问题
现象 本人想在主页面加载的时候调用子组件的方法。示例代码如下: 运行,发现 this.$refs 取不到。如下图所示: 解决方法,把onLoad 换为 onReady 就可以了。...
常見算法時間複雜度分析
当我们进行算法分析时,通常会忽略掉常数倍数的因子和低阶项,只考虑最高阶的项。这是因为在大规模问题下,较小的项和常数倍数的因子相对于最高阶的项来说变得可以忽略不计。 以下是一些常见的示例,说明了常数倍数的因子和高阶项对…...
自学Python05-学会Python中的函数定义
亲爱的同学们,今天我们将开始学习 Python 中的函数。函数就像一个魔法盒子,可以让我们在程序中执行一段代码,并且可以反复使用。这样,我们的程序就可以变得更加简洁和易于理解。现在,让我们一起来学习如何使用函数吧&a…...
设计模式-组合模式(Composite)
文章目录 前言一、组合模式的概念二、组合模式的优缺点1.优点2.缺点 三、组合模式的实现总结 前言 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树状结构以表示“整体-部分”的层次结构。组合模式使得客户端可以统…...
架构核心技术之微服务架构
小熊学Java:https://www.javaxiaobear.cn/,文末有免费资源 本文我们来学习微服务的架构设计 主要包括如下内容。 单体系统的困难:编译部署困难、数据库连接耗尽、服务复用困难、新增业务困难。 微服务框架:Dubbo 和 Spring Clou…...
SQL Server2022版+SSMS安装教程(保姆级)
SQL Server2022版SSMS安装教程(保姆级) 一,安装SQL Server数据库 1.下载安装包 (1)百度网盘下载安装包 链接:https://pan.baidu.com/s/1A-WRVES4EGv8EVArGNF2QQ?pwd6uvs 提取码:6uvs &…...
go语言基础---8
Http请求报文格式分析 package mainimport ("fmt""net" )func main() {//监听listener, err : net.Listen("tcp", ":8000")if err ! nil {fmt.Println("listener err", err)return}defer listener.Close()//阻塞等待用户的…...
Oracle的 dblink 学习笔记
文章目录 一、基础环境二、适用场景三、过程和方法四、参考资料 版权声明:本文为CSDN博主「杨群」的原创文章,遵循 CC 4.0 BY-SA版权协议,于2023年9月10日首发于CSDN,转载请附上原文出处链接及本声明。 原文链接:http…...
任意文件上传
1.任意文件上传概述 1.1 漏洞成因 服务器配置不当,开启了PUT 方法。 Web 应用开放了文件上传功能,没有对上传的文件做足够的限制和过滤。在程序开发部署时,没有考虑以下因素,导致限制被绕过: 代码特性 组件漏洞&am…...
【Unity3D】UI Toolkit自定义元素
1 前言 UI Toolkit 支持通过继承 VisualElement 实现自定义元素,便于通过脚本控制元素。另外,UI Toolkit 也支持将一个容器及其所有子元素作为一个模板,便于通过脚本复制模板。 如果读者对 UI Toolkit 不是太了解,可以参考以下内容…...
layui手机端使用laydate时间选择器被输入法遮挡的解决方案
在HTML中,你可以使用input元素的readonly属性来禁止用户输入,但是这将完全禁用输入,而不仅仅是禁止弹出输入法。如果你想允许用户在特定条件下输入,你可以使用JavaScript来动态地切换readonly属性。 readonly属性 增加readonly属…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
