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之CRUDhttps://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属…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...

【笔记】结合 Conda任意创建和配置不同 Python 版本的双轨隔离的 Poetry 虚拟环境
如何结合 Conda 任意创建和配置不同 Python 版本的双轨隔离的Poetry 虚拟环境? 在 Python 开发中,为不同项目配置独立且适配的虚拟环境至关重要。结合 Conda 和 Poetry 工具,能高效创建不同 Python 版本的 Poetry 虚拟环境,接下来…...
【Java基础】向上转型(Upcasting)和向下转型(Downcasting)
在面向对象编程中,转型(Casting) 是指改变对象的引用类型,主要涉及 继承关系 和 多态。 向上转型(Upcasting) ⬆️ 定义 将 子类对象 赋值给 父类引用(自动完成,无需强制转换&…...