Spring MVC异步上传、跨服务器上传和文件下载
一、异步上传
之前的上传方案,在上传成功后都会跳转页面。而在实际开发中,很多情况下上传后不进行跳转,而是进行页面的局部刷新,比如:上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。
1.1 JSP页面
编写JSP页面,引入jQuery和jQuery表单上传工具jquery.form.js【该js文件已经上传到我的资源,有需要的小伙伴可以自行下载】
upload4.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>上传</title><script src="/js/jquery-2.1.1.min.js"></script><script src="/js/jquery.form.js"></script>
</head>
<body>
<h3>文件上传</h3>
<form id="ajaxForm" enctype="multipart/form-data"><input type="file" name="file"/><%-- 按钮类型不能是submit,否则会刷新页面 --%><input type="button" value="上传头像" id="btn"/><!-- 上传头像后展示的位置 --><img src="/" width="100" id="img"><script>$(function () {$("#btn").click(function () {// 异步提交表单$("#ajaxForm").ajaxSubmit({url: "/fileUpload4",type: "post",success: function (data) {$("#img").attr("src", data);console.log(data);}})})})</script>
</form>
</body>
</html>
1.2 控制器方法
// 接收异步上传请求@RequestMapping("/fileUpload4")// 不进行页面跳转@ResponseBodypublic String upload3(HttpServletRequest request,MultipartFile file) throws Exception{// 1.设置上传文件保存的文件夹,存放上传的文件String realPath = request.getSession().getServletContext().getRealPath("/upload");File dir = new File(realPath);if(!dir.exists()){dir.mkdirs();}// 拿到上传文件名String filename = file.getOriginalFilename();filename = UUID.randomUUID()+"_"+filename;// 创建空文件File newFile = new File(dir,filename);// 将上传的文件写到空文件中file.transferTo(newFile);System.out.println("/upload/"+filename);return "/upload/"+filename;}
1.3 测试结果
访问路径:http://localhost:8080/upload4.jsp

OK,我们可以看得出来确实只刷新了头像那一部分的页面。本次案例成功实现
二、跨服务器上传

由于文件占据磁盘空间较大,在实际开发中往往会将文件上传到其他服务器中,此时需要使用跨服务器上传文件。
2.1 修改tomcat的部分配置
1. 解压tomcat作为图片服务器,在tomcat的webapps下创建upload目录作为文件上传目录。

这是我自己的tomcat安装目录,新建一个upload文件夹。
2. 修改tomcat的 conf/web.xml 文件,支持跨服上传。
<servlet> <init-param> <param-name>readonly</param-name><param-value>false</param-value> </init-param>
</servlet>
3. 修改tomcat的 conf/server.xml 文件,修改tomcat端口,修改完开启tomcat服务器,如下图:
<Connector port="8081" protocol="HTTP/1.1"connectionTimeout="20000" redirectPort="8443" />

双击运行

出现该页面,不要关闭这个页面!!!
2.2 JSP页面
这里的内容和上面的JSP没有区别!只是响应的路径不一样。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>上传</title><script src="/js/jquery-2.1.1.min.js"></script><script src="/js/jquery.form.js"></script>
</head>
<body>
<h3>文件上传</h3>
<form id="ajaxForm" enctype="multipart/form-data"><input type="file" name="file"/><%-- 按钮类型不能是submit,否则会刷新页面 --%><input type="button" value="上传头像" id="btn"/><!-- 上传头像后展示的位置 --><img src="/" width="100" id="img"><script>$(function () {$("#btn").click(function () {// 异步提交表单$("#ajaxForm").ajaxSubmit({url: "/fileUpload5",type: "post",success: function (data) {$("#img").attr("src", data);console.log(data);}})})})</script>
</form>
</body>
</html>
2.3 添加依赖
这里我们需要在pom.xml添加跨服上传依赖
<!-- 跨服上传 --><dependency><groupId>com.sun.jersey</groupId><artifactId>jersey-core</artifactId><version>1.18.1</version></dependency><dependency><groupId>com.sun.jersey</groupId><artifactId>jersey-client</artifactId><version>1.18.1</version>
2.4 控制器方法
创建控制器方法,该方法在接受到上传请求后将文件保存到其他服务器上。
// 该方法接收到上传请求后将文件保存到其他服务器上@RequestMapping("/fileUpload5")@ResponseBodypublic String upload4(HttpServletRequest request,MultipartFile file) throws Exception{// 设置跨服上传的服务器路径String path = "http://localhost:8081/upload/";// 获取上传的文件名String filename = file.getOriginalFilename();filename = UUID.randomUUID()+"_"+filename;// 跨服上传:// 1.创建客户端对象Client client = Client.create();// 2.使用客户端对象连接图片服务器WebResource resource = client.resource(path+filename);// 3.传输数据resource.put(file.getBytes());System.out.println(path+filename);return path+filename;}
2.5 测试结果
访问路径:http://localhost:8080/upload5.jsp

可以看得到确实成功上传到了服务器上面的upload目录下
三、文件下载
将文件上传到服务器后,有时我们需要让用户下载上传的文件,接下来我们编写文件下载功能:
3.1 查询可下载文件方法
编写控制器方法,查询所有可下载的文件(我这里是查询存放在/webapps/upload/目录下的图片),并跳转到下载页面
// 查询可下载的文件@RequestMapping("/showFiles")public String showFileDown(HttpServletRequest request, Model model){// 1.获取下载文件路径集合。注:跨服务器上传中,网络路径无法获取文件列表。String path = request.getSession().getServletContext().getRealPath("/upload");File file = new File(path);String [] files = file.list();// 2.将路径放入模型中,跳转到JSP页面model.addAttribute("files",files);return "download";}
3.2 添加JSTL依赖
<!-- 添加JSTL依赖 --><dependency><groupId>org.apache.taglibs</groupId><artifactId>taglibs-standard-spec</artifactId><version>1.2.5</version></dependency><dependency><groupId>org.apache.taglibs</groupId><artifactId>taglibs-standard-impl</artifactId><version>1.2.5</version></dependency>
3.3 编写下载页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>下载</title>
</head>
<body>
<h3>文件下载</h3>
<%-- 遍历文件集合 --%>
<c:forEach items="${files}" var="file"><a href="/download?fileName=${file}">${file}</a><br/>
</c:forEach>
</body>
</html>
3.4 下载控制器方法
// 文件下载@RequestMapping("/download")public void fileDown(HttpServletRequest request, HttpServletResponse response,String fileName) throws Exception{// 设置响应头response.setHeader("Content-Disposition","attachment;filename="+fileName);// 获取文件路径String path = request.getSession().getServletContext().getRealPath("/upload");File file = new File(path,fileName);// 获取字节输出流ServletOutputStream os = response.getOutputStream();// 使用输出流写出文件os.write(FileUtils.readFileToByteArray(file));os.flush();os.close();}
3.5 测试结果
OK,我们先来访问http://localhost:8080/showFiles
查询出所有可以下载的文件:然后点击下载也是可以成功下载,文件的上传和下载就学习到这里了。

往期专栏&文章相关导读
大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。
1. Maven系列专栏文章
| Maven系列专栏 | Maven工程开发 |
| Maven聚合开发【实例详解---5555字】 |
2. Mybatis系列专栏文章
| Mybatis系列专栏 | MyBatis入门配置 |
| Mybatis入门案例【超详细】 | |
| MyBatis配置文件 —— 相关标签详解 | |
| Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填 | |
| Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分) | |
| Mybatis分页查询——四种传参方式 | |
| Mybatis一级缓存和二级缓存(带测试方法) | |
| Mybatis分解式查询 | |
| Mybatis关联查询【附实战案例】 | |
| MyBatis注解开发---实现增删查改和动态SQL | |
| MyBatis注解开发---实现自定义映射关系和关联查询 |
3. Spring系列专栏文章
| Spring系列专栏 | Spring IOC 入门简介【自定义容器实例】 |
| IOC使用Spring实现附实例详解 | |
| Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式 | |
| Spring DI简介及依赖注入方式和依赖注入类型 | |
| Spring IOC相关注解运用——上篇 | |
| Spring IOC相关注解运用——下篇 | |
| Spring AOP简介及相关案例 | |
| 注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】 | |
| Spring事务简介及相关案例 | |
| Spring 事务管理方案和事务管理器及事务控制的API | |
| Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务 |
4. Spring MVC系列专栏文章
| SpringMVC系列专栏 | Spring MVC简介附入门案例 |
| Spring MVC各种参数获取及获取方式自定义类型转换器和编码过滤器 | |
| Spring MVC获取参数和自定义参数类型转换器及编码过滤器 | |
| Spring MVC处理响应附案例详解 | |
| Spring MVC相关注解运用 —— 上篇 | |
| Spring MVC相关注解运用 —— 中篇 | |
| Spring MVC相关注解运用 —— 下篇 | |
| Spring MVC多种情况下的文件上传 | |
| Spring MVC异步上传、跨服务器上传和文件下载 | |
| Spring MVC异常处理【单个控制异常处理器、全局异常处理器、自定义异常处理器】 | |
| Spring MVC拦截器和跨域请求 | |
| SSM整合案例【C站讲解最详细流程的案例】 |
相关文章:
Spring MVC异步上传、跨服务器上传和文件下载
一、异步上传 之前的上传方案,在上传成功后都会跳转页面。而在实际开发中,很多情况下上传后不进行跳转,而是进行页面的局部刷新,比如:上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。 1.1 JSP页面 …...
性能测试之并发用户数的估计
在计算并发用户数之前,需要先了解2个概念。 并发用户:指的是现实系统中同时操作业务的用户,在性能测试工具中一般称为虚拟用户。并发用户这些用户的最大特征是和服务器产生了交互,这种交互既可以是单向的传输数据,也可…...
【全方位解析】如何获取客户端/服务端真实 IP
一、应用场景 1.比如在投票系统开发中,为了防止刷票,我们需要限制每个 IP 地址只能投票一次 2.当网站受到诸如 DDoS(Distributed Denial of Service,分布式拒绝服务攻击)等攻击时,我们需要快速定位攻击者…...
Ceph简介和特性
Ceph是一个多版本存储系统,它把每一个待管理的数据流(例如一个文件) 切分为一到多个固定大小的对象数据,并以其为原子单元完成数据存取。 对象数据的底层存储服务是由多个主机 (host) 组成的存储集群,该集群也被称之为 RADOS (ReliableAutoma…...
Python基本语法之符号使用
好久没有和小伙伴们更新python了,我对于此感到抱歉以后有时间尽量多更新 目录 一. 标识符 A.定义: B.使用特点 C.Python标识符,进一步探讨以下几个方面的详细内容: 1. 规则和约定: 2. 有效的标识符示例࿱…...
前端vue部署到nginx并且配置https安全证书全流程
说明一下: 本人原本使用的是docker安装nginx通过挂载实现部署,但是出现了很多bug(例如部署安全证书后还是无法访问),所以困扰了很久,最后改为本地安装nginx,最终在不懈的努力下终于按照好了&…...
三子棋(超详解+完整码源)
三子棋 前言一,游戏规则二,所需文件三,创建菜单四,游戏核心内容实现1.棋盘初始化1.棋盘展示3.玩家下棋4.电脑下棋5.游戏胜负判断6.game()函数内部具体实现 四,游戏运行实操 前言 C语言实现三子棋…...
【算法提高:动态规划】1.2 最长上升子序列模型(TODO:最长公共上升子序列)
文章目录 题目列表1017. 怪盗基德的滑翔翼1014. 登山482. 合唱队形1012. 友好城市(⭐排序后 最长上升子序列模型)1016. 最大上升子序列和1010. 拦截导弹解法1——最长递减子序列 贪心解法2——最长递减子序列 最长递增子序列(⭐贪心结论&am…...
会不会好奇ai绘画生成器?ai创作的灵感从何而来?
在这个宁静的公园里,阳光透过树叶的缝隙洒在的地面上,微风轻拂着艺术家的发丝,带来一丝清凉。坐在长椅上的他,手中紧握着一支触控画笔,目光凝视着眼前的美景。旁边一台智能绘画助手正在悄悄发光,它似乎能够…...
【Ajax】笔记-JQuery发送请求与通用方法
Get请求 语法格式: $.get(url, [data], [callback], [type]) url:请求的 URL 地址。data:请求携带的参数。callback:载入成功时回调函数。type:设置返回内容格式,xml, html, script, json, text, _default。 准备三个按钮分别测试Get 、Post、通用型方…...
视频的音频提取怎么做?这样提取很简单
提取视频中的音频通常在需要从视频中独立使用音频或需要对音频进行编辑时使用。例如,当我们需要将音频上传到音乐流媒体平台或将其用于播客或其他音频项目时,就可能需要从视频中提取音频。问题是该怎么提取呢?教给大家几种简单的提取方法&…...
几百本常用计算机开发语言电子书链接
GitHub - XiangLinPro/IT_book: 本项目收藏这些年来看过或者听过的一些不错的常用的上千本书籍,没准你想找的书就在这里呢,包含了互联网行业大多数书籍和面试经验题目等等。有人工智能系列(常用深度学习框架TensorFlow、pytorch、keras。NLP、…...
Docker Compose 解析:定义和管理多容器应用,从多角度探索其优势和应用场景
🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~ἳ…...
Linux系列---【CentOS 7通过MSTSC连接远程桌面】
安装对应的yum源 yum list lightdm xorgxrdp xrdp 可以看到这些软件都在epel中,如果没有的话,请先安装对应的yum源。命令如下: yum install -y epel-release 确认yum源没有问题之后,我们就可以进行安装了。 安装lightdm xorgxrdp…...
width: calc(~“100% - 267px“);动态css 调样式
.result-filtering {color: #8b8b8b;display: flex;// width: 82.6%;width: calc(~"100% - 267px");}...
Windows Server 2012 搭建网关服务器并端口转发
需求 使用 Windows server 作为Hyper-V 虚拟出许多虚拟机,基本上都分配了内网地址,现在需要这些虚拟机访问外网,或者外网直接访问这些虚拟机,必须配置一个网关服务器。我决定直接使用 Windows 的远程访问中的 NAT 服务来完成。 …...
基于linux下的高并发服务器开发(第三章)- 3.10 死锁
deadlock.c #include <stdio.h> #include <pthread.h> #include <unistd.h>// 全局变量,所有的线程都共享这一份资源。 int tickets 1000;// 创建一个互斥量 pthread_mutex_t mutex;void * sellticket(void * arg) {// 卖票while(1) {// 加锁pt…...
09.计算机网络——套接字编程
文章目录 网络字节序socket编程socket 常见APIsockaddr结构 UDP编程创建socket绑定socketsendto发送数据recvform接收数据关闭socket TCP编程创建socket绑定socketlisten监听套接字accept服务端接收连接套接字connect客户端连接套接字send发送数据recv接收数据关闭socket 工具n…...
Data Structure, Algorithm,and Applications in C++
在学习这本书进阶内容之前,我们可以跟着它的第一章部分再巩固和复习。本书由Sartaj Sahni撰写,由王立柱和刘志红翻译。全书通俗易懂,内容丰富,是巩固C内容的不二选择。希望本文对各位有所帮助。 目录 1.函数与参数 1.1.传值参数…...
Apipost使用教程
Apipost是一款集API调试、生成文档、Mock、测试于一体的协同工具。单个工具可以同时满足接口测试、生成/分享文档、Mock、流程测试等功能,还有超实用的多人多角色间实时协作的功能。将前端、后端、测试三种角色串联起来,从而实现工作流程无缝衔接、提高研…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...
