网站首页 > 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 实现文件的上传、下载、删除
欢迎 你 发表评论:
- 最近发表
- 标签列表
-
- 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)

本文暂时没有评论,来添加一个吧(●'◡'●)