Java文件下载/下载文件的案例

文章目录

  • 需求
  • 分析
  • 实现步骤
  • 示例代码
  • 下载的文件中文名显示问题

需求

1.页面显示超链接
2.点击超链接后弹出下载对话框
3.完成图片文件下载

分析

超链接指向的资源如果能够被浏览器解析,则直接在浏览器中展示,如果不能解析,则弹出下载提示框。如果希望无论返回什么资源都不要解析,而是让用户下载,那么就必须使用 content-disposition 响应头告诉客户端,返回的资源(响应体的数据)以附件的形式打开。

实现步骤

1.开发前端页面,使用超链接标签,href 属性指向一个 Servlet,并且传递下载资源的名称
2.实现后端逻辑,定义一个 Servlet,获取下载资源的名称,再根据资源名称将对应的资源加载入内存中,再从内存输出到 Response对象中,再返回给客户端
2.1.获取参数
2.2.使用字节输入流读取资源文件,加载进内存中
2.3.设置响应头(content-type 和 content-disposition)
2.4.使用字节输出流写入到 Response 对象中。具体是从内存写入到 Response 的字节输出流中,再从字节输出流写入到 Response 对象中
2.5.服务器从 Response 对象中获取数据构建成响应报文发送给客户端(这步服务器自动完成)

说明:

response.setHeader("content-disposition", "attachement;filename=123.jpeg");

上述代码表示将响应头 content-disposition 的值设为 attachement;filename=123.jpeg。其中 attachement 表示响应的资源以附件形式打开;filename 是弹出的下载对话框中显示的文件名称以及文件下载后的文件名称。

示例代码

前端页面示例代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<a href="/servlet_demo/download?fileName=1.jpeg">图片</a>
<a href="/servlet_demo/download?fileName=1.avi">视频</a>
</body>
</html>

服务端示例代码:

package priv.lwx.javaex.servlet_demo.web.servlet.download;
/*** description** @author liaowenxiong* @date 2022/1/12 21:57*/import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;@WebServlet("/download")
public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.获取请求参数fileNameString fileName = request.getParameter("fileName");// 2.使用字节输入流加载文件进内存// 2.1.获取文件的服务器路径String realPath = this.getServletContext().getRealPath("/image/" + fileName);// 2.2.获取文件的文件字节输入流(用文件字节流关联文件)FileInputStream fis = new FileInputStream(realPath); // 这步就完成了读取文件数据进内存的操作System.out.println(fis);// 3.设置响应头// 3.1.设置响应头content-typeServletContext context = this.getServletContext();// 获取文件的MIME类型String mimeType = context.getMimeType(fileName);// 告诉客户端响应体的数据类型response.setHeader("content-type", mimeType);// 3.2.设置响应头content-dispositionresponse.setHeader("content-disposition", "attachement;filename=" + fileName);// 4.将输入流的数据写入到输出流中(类似文件复制的操作)// 4.1.获取字节输出流ServletOutputStream sos = response.getOutputStream();// 4.2.定义读取到的字节数据的缓冲区byte[] buff = new byte[1024 * 8];int len = 0;// 将字节数据读取到字节数组中,返回读取到的字节数,如果返回的字节数不是-1,说明没有读到文件末尾// 注意:字节输入流每次读取到字节数组中的数据会覆盖原来的旧数据while ((len = fis.read(buff)) != -1) {// 将字节数组中的字节数据写入到字节输出流中,sos.write(buff, 0, len);}// 5.释放资源fis.close();}
}

下载的文件中文名显示问题

如果你下载的文件名称是中文,不同浏览器版本会有不同的显示,不过都是错误的显示。

解决的办法:判断浏览器的版本,根据不同的浏览器版本对文件名进行不同的编码,再返回给客户端显示。

处理文件名称的示例代码如下:

package priv.lwx.javaex.servlet_demo.util;import Decoder.BASE64Encoder;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;/*** 处理下载文件的中文名无法显示的问题** @author liaowenxiong* @date 2022/1/13 11:55*/public class DownloadUtils {public static String getFileName(String agent, String filename) throws UnsupportedEncodingException, UnsupportedEncodingException {if (agent.contains("МЅIЕ")) {// IE浏览器filename = URLEncoder.encode(filename, "utf-8");filename = filename.replace("+", " ");} else if (agent.contains("Firefox")) {//火狐浏览器BASE64Encoder base64Encoder = new BASE64Encoder();filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";} else {//其它浏览器filename = URLEncoder.encode(filename, "utf-8");}return filename;}
}

最终完整的文件下载的示例代码:

package priv.lwx.javaex.servlet_demo.web.servlet.download;
/*** 文件下载的示例代码** @author liaowenxiong* @date 2022/1/12 21:57*/import priv.lwx.javaex.servlet_demo.util.DownloadUtils;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;@WebServlet("/download")
public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.获取请求参数fileNameString fileName = request.getParameter("fileName");// 2.使用字节输入流加载文件进内存// 2.1.获取文件的服务器路径String realPath = this.getServletContext().getRealPath("/image/" + fileName);// 2.2.获取文件的文件字节输入流(用文件字节流关联文件)FileInputStream fis = new FileInputStream(realPath); // 这步就完成了读取文件数据进内存的操作// System.out.println(fis);// 3.设置响应头// 3.1.设置响应头content-typeServletContext context = this.getServletContext();// 获取文件的MIME类型String mimeType = context.getMimeType(fileName);// 告诉客户端响应体的数据类型response.setHeader("content-type", mimeType);// 3.2.设置响应头content-disposition// 获取请求头user-agent/* String agent = request.getHeader("user-agent");// 根据浏览器版本对文件名进行不同的处理,以解决中文无法显示的问题fileName = DownloadUtils.getFileName(agent, fileName);*/response.setHeader("content-disposition", "attachement;filename=" + fileName);// filename是在下载提示框显示的文件名// 4.将输入流的数据写入到输出流中(类似文件复制的操作)// 4.1.获取字节输出流ServletOutputStream sos = response.getOutputStream();// 4.2.定义读取到的字节数据的缓冲区byte[] buff = new byte[1024 * 8];int len = 0;// 将字节数据读取到字节数组中,返回读取到的字节数,如果返回的字节数不是-1,说明没有读到文件末尾// 注意:字节输入流每次读取到字节数组中的数据会覆盖原来的旧数据while ((len = fis.read(buff)) != -1) {// 将字节数组中的字节数据写入到字节输出流中,sos.write(buff, 0, len);}// 5.释放资源fis.close();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

公司电脑监控软件_公司电脑监控软件,如何限制公司电脑网络游戏

在互联网领域里&#xff0c;游戏行业之所以不断推陈出新&#xff0c;种类繁多&#xff0c;最根本的原因还是由于其用户的广泛性&#xff0c;市场的巨大性。玩网络游戏已经是我们身边最为常见的休闲方式&#xff0c;手机、电脑、平板电脑&#xff0c;方便的数码设备为我们提供了…

derby数据库的数据_Derby数据库备份

derby数据库的数据抽象 我已经发布了许多有关Derby的博客&#xff1a; 同一主机上的多个Derby网络服务器 Apache Derby数据库用户和权限 与Maven和内存中Derby数据库的集成测试 这本不打算是一个系列。 但是多年来&#xff0c;我越来越多地使用Derby。 最近&#xff0c;我开…

Servlet中获取请求行的数据

package priv.lwx.javaex.servlet_demo.web.servlet.request; /*** 获取请求行的数据** author liaowenxiong* date 2021/12/29 09:22*/import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import j…

没有内存条电脑能开机吗_开机键过时了!3种电脑开机方法,能让你睡懒觉的技术还不快来学...

电脑开机谁都会&#xff0c;按下电源键等他几十秒就好。不过还有其他的开机方式&#xff0c;有的能让你睡懒觉&#xff0c;有的能让你炫技&#xff0c;还有更多创意等你发挥&#xff0c;想不想来尝试一下呢&#xff1f;能睡懒觉的定时开机如果有每天定时开机的需求&#xff0c;…

c语言编程数独游戏,编程做数独游戏

数独游戏非常好玩&#xff0c;可以训练玩家的逻辑推理能力。数独游戏的规则是&#xff1a;1&#xff0e;在99的大九宫格内&#xff0c;已给定若干数字&#xff0c;其他宫位留白&#xff0c;玩家需要自己按照逻辑推敲出剩下的空格里是什么数字。2&#xff0e;必须满足的条件&…

反引号包裹反引号_五个金色反引号

反引号包裹反引号五种琴弦 从Java 1.0开始&#xff0c;我们就有了字符串文字"like this" 。 我们还想要其他什么字符串&#xff1f; 其他编程语言为我们提供&#xff1a; 表达式插值&#xff1a; s"I am ${age - 10} years old." 插值格式&#xff1a; f…

c语言iota怎么用,C++ std::iota用法及代码示例

存储顺序递增分配val的[first&#xff0c;last]个连续值范围内的每个元素&#xff0c;就像在写入每个元素之后以 val递增。模板&#xff1a;void iota (ForwardIterator first, ForwardIterator last, T val);参数&#xff1a;first, lastForward iterators to the initial and…

web自动化如何在不同浏览器运行_自动化决策环节的“心脏”将如何与众不同?...

原标题&#xff1a;自动化决策环节的“心脏”将如何与众不同&#xff1f;原宝钢研究院首席研究员郭朝晖博士认为&#xff1a;自动化本质是感知、决策和执行的统一自动化的理论基础是控制论。控制论诞生时&#xff0c;控制论之父维纳思考了这样一个问题&#xff1a;机器和人(动物…

Servlet中获取请求头的数据

package priv.lwx.javaex.servlet_demo.web.servlet.request;/*** 获取请求头的数据** author liaowenxiong* date 2021/12/29 11:21*/ import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.ut…

jdk8 :: 什么意思_JDK 13:什么是AggressiveOpts?

jdk8 :: 什么意思JVM 11中已弃用Java VM标志-XX:AggressiveOpts [请参见JDK-8199777和JDK-8199778 ]“因为其行为是不明确的。” JDK-8199778的“问题”部分进一步解释了&#xff08;我强调了 &#xff09;&#xff1a; AggressiveOpts已被用作实现各种实验性能功能的一种包罗…

c语言递归函数检测回文,在C中使用递归函数的回文测试

我试图编写用于测试字符串的程序&#xff0c;如果它是回文或不是&#xff0c;但我总是得到输出&#xff0c;因为它不是一个。我的代码有什么问题&#xff1f;在C中使用递归函数的回文测试#include #include int is_palindrome(int start, int end, char *str){if (str[start] !…

获取macos mojave_高仿MacOS教程

“潮办公”关注我们拥有一台MacBook是很多人的梦想&#xff0c;但是高昂的售价成功逼退了一大波人。MacBook一直以颜值高、轻薄、系统流畅而出名&#xff0c;那么其他的小伙伴们想体验一波苹果系统怎么办&#xff1f;这个软件或许能帮你。Part 1安装Mydockmydock是windows下的一…

Servlet中防止盗链的代码

package priv.lwx.javaex.servlet_demo.web.servlet.request;/*** 获取referer&#xff0c;防止盗链** author liaowenxiong* date 2021/12/29 11:21*/import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpSer…

android wtf_WTF连接池

android wtf让我们谈谈连接池。 我声称&#xff1a; 大多数流行的连接池的默认设置都很差&#xff01; 对您来说&#xff0c;这意味着&#xff1a; 去查看您的连接池设置。 如果您依赖默认设置&#xff0c;则可能会遇到问题。 您可能有内存泄漏和应用程序无响应&#xff08…

c语言实验5上机刘若慧2017年,《《 C语言程序设计案例教程》》.ppt

《《 C语言程序设计案例教程》》.ppt课堂练习&#xff1a; 7、求三个整数之和&#xff1a; 1 只用main函数 2 用求两个整数之和的函数实现 main int a, b, c, sum; scanf “%d, %d,%d”, &a, &b, &c &#xff1b; sum abc; printf “sum %d\n”,sum ; printf “%d%…

c++ vs 输出log到窗口_欧冠豪门碰撞,尤文vs巴萨,曼联vs红牛

点击上方蓝色字关注我们 “ 欧冠第二轮昨日完成8场比赛&#xff0c;3胜3平2负&#xff0c;各队保平争胜策略明显。今日各豪门再出发&#xff0c;竞彩推出4场热门比赛。热门014尤文vs巴萨&#xff0c;015曼联vs莱比锡红牛。”01—周三014 欧冠 尤文图斯vs巴塞罗那 2020-10-29 04…

Servlet中判断浏览器版本的代码

package priv.lwx.javaex.servlet_demo.web.servlet.request;/*** 获取user-agent&#xff0c;判断浏览器版本** author liaowenxiong* date 2021/12/29 11:21*/import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.htt…

jakarta ee_在等待Jakarta EE时

jakarta ee自Oracle在JavaOne 2017宣布将Java™EE转移到Eclipse Foundation以来已有一年多了。此后&#xff0c;发生了很多事情&#xff1a; Java™EE 8 API和实现项目已在EE4J下建立 。 Eclipse GlassFish 5.1 即将发布 。 全新的Jakarta EE规范流程指日可待。 社区显示出…

c语言解析分隔符文本,c – 使用分隔符读取文件

正如其他两个答案所指出的那样,你必须使用std :: getline,但这就是我要做的&#xff1a;if (std::getline(is, zipcode, ,) &&std::getline(is, city, ,) &&std::getline(is, state)){d.zipCode std::stoi(zipcode);}我做的唯一真正的改变是我将提取包含在if语…

很高兴加入 英文_XR车载公司Holoride加入高通XR计划

原标题&#xff1a;XR车载公司Holoride加入高通XR计划XR车载公司Holoride进来了高通的Qualcomm XR Eneerprise决策 你大约没有听说过holoride&#xff0c;但你势必听说过高通公司。下面我们就来看看Holoride&#xff0c;他是一家确立两年的XR车载公司&#xff0c;起劲于提供家用…