网站首页 > java教程 正文
Servlet 实现文件下载
在生活或者工作中,总是避免不了下载文件,下载的东西有各种类型,譬如图片,视频,文本,文档,音乐等等,这些东西有大有小,大的有几G到几十G,小的或许只有几K。这些东西究竟是如何从服务器下载到我们本地的呢?现在就利用 Servlet 来实现一个的文件下载功能。
前提
要想完成这个案例,需要如下技术:
Java 基础
HTML 基础
会使用 Tomcat 服务器
会使用 Servlet 进行开发
了解 HTTP 协议
会使用 Response 设置响应头、响应消息行
准备工作
所谓工欲善其事,必先利其器。要完成这个案例,我们得做好准备工作。
首先,打开
Eclipse
,新建一个Dynamic Web Project
。键入项目名,选择运行时环境为
Apache Tomcat v7.0
,选择 web 版本为2.5
,然后点击Finished
。在项目的
WebContent
目录下,新建一个文件夹download
,然后将可以供给用户下载的文件存放在这个文件夹里。
在
WebContent
目录下新建一个index.html
。在
WebContent
->WEB-INF
目录下新建一个web.xml
文件,这是web2.5
版本的规范,一个web.xml
文件可以对 web 项目进行基本的配置。
代码如下:
<!DOCTYPE html><html>
代码如下:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
将服务器启动,然后在浏览器中输入:
http://localhost:8080/download
。如果出现以下界面,那么恭喜你,准备工作完美完成!使用
Tomcat
将次项目发布,并在浏览器中预览。
完成案例
超链接下载文件
也许有人会说,下载文件有什么难的,在 index.html
中编写几个 a
标签,将 href
属性设置为供给用户下载的文件的路径不就行了?
那么,我就按照上述所说试验:
首先,在 index.html
中编写3个 a
标签,将 href
属性分别指向了供给用户下载的文件的路径。
<!DOCTYPE html><html>
然后,在浏览器中打开 index.html
。
这样看似乎并没有什么问题,那么来点击超链接试验一下。
结果,有的文件直接在浏览器打开了,而有的文件则是下载了。这究竟是什么原因呢?原来,当浏览器能够解析该文件的 MIME类型,则直接打开该文件;若不能,则下载。
如此,看来使用超链接下载文件是行不通了。
编码下载
从以上分析可以看出,要实现文件下载并不是设置 a
标签那么简单的。那么,究竟该怎样实现文件下载功能呢?此时,就需要使用 Servlet 编码读取要下载的文件,然后写到响应流中以达到用户下载文件的目的。
在这里,我们使用 get
请求方式,将文件名放在 url
中传送给服务器,但在很多情况下使用 post
发送数据给服务器更加合适。通过 get
发送大量数据是不现实的,它有一定的局限性,在这里使用 get
方式只是为了方便。
首先,新建一个 Servlet
,并编写 web.xml
设置它的访问路径:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
然后,需要修改 index.html
页面中 a
标签的 href
属性:
<!DOCTYPE html><html>
接下来,就可以开始编写 Servlet 了:
首先,从
url
中获取文件名String filename = request.getParameter("name");
接下来,获取根据文件名获取文件的 MIME类型
String mimeType = getServletContext().getMimeType(filename);
然后,就需要设置文件的 MIME类型
response.setContentType(mimeType);
上条语句的作用就是使客户端浏览器,区分不同种类的数据,并根据不同的 MIME类型 调用浏览器内不同的程序嵌入模块来处理相应的数据。例如浏览器就是通过 MIME类型 来判断文件是 gif 图片,还是 doc 文档的。
光是这些还不行,下面还要告诉浏览器 “我要下载东西”
response.setHeader("content-disposition", "attachment;filename=" + filename);
最后,把文件从服务器拷贝到浏览器,完成下载
// 定义输入流InputStream is = getServletContext().getResourceAsStream("/download/" + filename);// 定义输出流ServletOutputStream os = response.getOutputStream();// 从文件中读入数据并写到输出字节流中int len = -1;byte[] bytes = new byte[1024];while ((len = is.read(bytes)) != -1) {
下面,我来测试一下:
如此看来,似乎也并没有什么问题,但是我设置的文件名都是数字,如果我将文件名都设置为中文,那么又会怎样呢?
此时,对于 get
请求,参数追加到地址栏,会使用 utf-8
编码,服务器(Tomcat)接受到请求之后,使用 iso-8859-1
解码,所以会出现乱码,导致找不到资源。
因此,我们在获取文件名时,必须将文件名用 utf-8
解码,然后才能使用。
String filename = new String(request.getParameter("name").getBytes("iso-8859-1"), "utf-8");
经过上述处理后,虽然能够下载了,但又出现了:浏览器无法识别文件名。
此时,我们需要编写一个工具类,以解决这个问题。
新建一个 class
,设置类名为 DownloadUtils
,编写一个静态方法,作用是根据浏览器的不同把传递过来的文件名编码。
package club.luckylight.util;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import javax.servlet.http.HttpServletRequest;public class DownloadUtils { public static String getFilename(HttpServletRequest request, String filename) throws UnsupportedEncodingException {
然后,在告诉浏览器 “我要下载东西” 之前,把文件名编码。
String newFilename = DownloadUtils.getFilename(request, filename);
根据测试,以上工具类可以解决主流浏览器(IE内核,Edge内核,Chrom,FireFox等)文件下载时文件名乱码问题。
完整代码
DownloadUtils.java
package club.luckylight.util;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import javax.servlet.http.HttpServletRequest;public class DownloadUtils { public static String getFilename(HttpServletRequest request, String filename) throws UnsupportedEncodingException {
DownloadServlet.java
package club.luckylight.servlet;import java.io.IOException;import java.io.InputStream;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import club.luckylight.util.DownloadUtils;public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取文件名,并设置编码
总结
至此,文件下载案例就完成了。其中有许多小细节并没有处理,如发现有什么错误,请多多指点。
- 上一篇: 100个Java工具类之6:文件的上传与下载
- 下一篇: JAVA WEB项目大文件上传下载源代码
猜你喜欢
- 2024-10-21 Spring WEB工程整合使用FTP,ftp文本文件解析入库,文件上传下载
- 2024-10-21 使用SFTP跟服务器传输文件(怎么用sftp上传文件到服务器)
- 2024-10-21 Ubuntu 下安装 JDK17(ubuntu中安装jdk)
- 2024-10-21 JasperReport生成pdf文件 Java开发pdf文件 pdf文件生成及下载
- 2024-10-21 用JavaEE实现前后台交互的文件上传与下载,适合小白入门练手!
- 2024-10-21 JAVA 大文件上传解决方案(500M以上)
- 2024-10-21 《数据结构与算法分析Java语言描述》PDF文件免费下载
- 2024-10-21 CDH安装系统环境准备——系统版本和安装包下载地址指南
- 2024-10-21 jar文件怎么打开(base.apk.1文件怎么打开)
- 2024-10-21 Java 实现 FastDFS 实现文件的上传、下载、删除
你 发表评论:
欢迎- 07-21如何将 iPhone 中的联系人导出到 Excel/CSV?
- 07-21sql查询的字段数据中有逗号。放到csv文件会分开,如何解决?
- 07-21在 WebAPI 里生成 csv zip 文件(webapi怎么发布在iis上)
- 07-21如何把csv格式转换成Excel格式(csv格式怎么转换)
- 07-21如何将高程导出为XYZ或CSV高程点(如何将高程数据导入cad)
- 07-21使用python把csv汇总成excel(python怎么将csv文件中的列存入列表)
- 07-21解决PHP导出CSV文件中文乱码问题(php导出excel文件)
- 07-21使用vba将Excel 文件转成 CSV 文件
- 最近发表
-
- 如何将 iPhone 中的联系人导出到 Excel/CSV?
- sql查询的字段数据中有逗号。放到csv文件会分开,如何解决?
- 在 WebAPI 里生成 csv zip 文件(webapi怎么发布在iis上)
- 如何把csv格式转换成Excel格式(csv格式怎么转换)
- 如何将高程导出为XYZ或CSV高程点(如何将高程数据导入cad)
- 使用python把csv汇总成excel(python怎么将csv文件中的列存入列表)
- 解决PHP导出CSV文件中文乱码问题(php导出excel文件)
- 使用vba将Excel 文件转成 CSV 文件
- python爬虫25 | 爬取的数据怎么保存?CSV了解一下
- MySQL 导出数据(mysql 导出数据 判断成功)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)