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++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...