22. Servlet入门 - 文件下载案例
22. Servlet入门 - 文件下载案例
案例-完成文件下载
1.需求分析
- 创建文件下载的列表的页面,点击列表中的某些链接,下载文件.
img/
2.文件下载分析
2.1什么是文件下载
将服务器上已经存在的文件,输出到客户端浏览器.
说白了就是把服务器端的文件拷贝一份到客户端, 文件的拷贝---> 流(输入流和输出流)的拷贝
2.2文件下载的方式
- 第一种:超链接方式(不推荐) 链接的方式:直接将服务器上的文件的路径写到href属性中.如果浏览器不支持该格式文件,那么就会提示进行下载, 如果 浏览器支持这个格式(eg: png, jpg....)的文件,那么直接打开,不再下载了
- 第二种:手动编码方式(推荐) 手动编写代码实现下载.无论浏览器是否识别该格式的文件,都会下载.
3.思路分析
3.1超链接方式
- 准备下载的资源(文件)
- 编写一个下载页面
- 在这个页面上定义超链接,指定href
3.2编码方式
3.2.1手动编码方式要求
设置两个头和一个流
设置的两个头:
Content-Dispostion: 服务器告诉浏览器去下载
Content-Type: 告诉浏览器文件类型.(MIME的类型)
设置一个流:
获得要下载的文件的输入流.
3.2.2思路
image-20191209150057781
4.代码实现
4.1 准备下载的资源(文件)
image-20210109125818515
4.2 编写一个提供下载的 download.html 页面
image-20210109130037678
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/download?fileName=1.jpeg">下载1.jpeg</a><br>
<a href="/download?fileName=3.png">下载3.png</a><br>
<a href="/download?fileName=demo.zip">下载demo.zip</a><br>
<a href="/download?fileName=毒液.jpeg">下载毒液.jpeg</a><br>
</body>
</html>
启动tomcat,访问页面如下:
image-20210109130130807
此时已经写好了 html 页面,那么下面就是实现 Servlet 程序了。
4.3 编写处理下载业务的 Servlet 程序
4.3.1 首先编写接收文件名
image-20210109135318506
@WebServlet("/download")
public class DownloadDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决请求参数的中文乱码
request.setCharacterEncoding("UTF-8");
//解决响应中文乱码
response.setContentType("text/html;charset=utf-8");
//1.接收参数,获取需要下载的文件名
String fileName = request.getParameter("fileName");
System.out.println("需要下载的文件名: " + fileName);
}
}
在浏览器访问 download.html ,查看获取的文件名:
image-20210109135547460
4.3.2 拼接文件下载路径,读取文件字节流 输出显示到浏览器上
image-20210109140134502
@WebServlet("/download")
public class DownloadDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决请求参数的中文乱码
request.setCharacterEncoding("UTF-8");
//解决响应中文乱码
response.setContentType("text/html;charset=utf-8");
//1.接收参数,获取需要下载的文件名
String fileName = request.getParameter("fileName");
System.out.println("需要下载的文件名: " + fileName);
//2.拼接文件下载路径,读取文件字节流 输出显示到浏览器上
InputStream is = getServletContext().getResourceAsStream("file/" + fileName); // 获取文件输入字节流
ServletOutputStream os = response.getOutputStream(); // 获取浏览器输出流
IOUtils.copy(is, os);
//3. 关闭资源
os.close();
is.close();
}
}
浏览器访问一个文件如下:
image-20210109140300491
可以看到显示的是字节码数据,我们可以再通过设置响应头的方式,通知浏览器这是什么文件类型,然后浏览器就会对应显示。
4.3.3 设置浏览器显示的文件类型
image-20210109140518071
//3.设置浏览器显示的文件类型
String mimeType = getServletContext().getMimeType(fileName);
response.setHeader("Content-Type",mimeType);
浏览器访问如下:
image-20210109140540217
image-20210109140638050
当点击 .zip 的文件,则会提示下载。
image-20210109140810631
4.3.4 通过浏览器下载文件,并设置下载的文件名
在上面我们打开图片的时候是直接在浏览器展示的,那么如果我们希望是直接下载该怎么操作呢?
还有上面在下载 demo.zip 文件的时候,发现下载后文件名被修改为 download.zip ,那么该怎么设置下载的文件名呢?
我们可以通过设置响应头来处理:
response.setHeader("Content-Disposition","attachment;filename="+fileName);
实现代码如下:
image-20210109141354809
浏览器测试如下:
image-20210109141422338
image-20210109141452948
我们可以看到,如果下载的文件为中文内容,那么文件名则无法正常显示。
5. 解决下载中文的文件名乱码问题
在上面我们下载中文名称的文件的时候,会出现乱码的情况,那么该怎么解决呢?
其实还是编码格式的问题,只要设置编码格式即可。下面来看看如果设置。
中文文件在不同的浏览器中编码方式不同:火狐是Base64编码, 其它浏览器(谷歌)是URL的utf-8编码
image-20210109142711952
@WebServlet("/download")
public class DownloadDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决请求参数的中文乱码
request.setCharacterEncoding("UTF-8");
//解决响应中文乱码
response.setContentType("text/html;charset=utf-8");
//1.接收参数,获取需要下载的文件名
String fileName = request.getParameter("fileName");
System.out.println("需要下载的文件名: " + fileName);
//2.拼接文件下载路径,读取文件字节流 输出显示到浏览器上
InputStream is = getServletContext().getResourceAsStream("file/" + fileName); // 获取文件输入字节流
ServletOutputStream os = response.getOutputStream(); // 获取浏览器输出流
//3.设置浏览器显示的文件类型
String mimeType = getServletContext().getMimeType(fileName);
response.setHeader("Content-Type",mimeType);
// 中文文件在不同的浏览器中编码方式不同:火狐是Base64编码, 其它浏览器(谷歌)是URL的utf-8编码
// 获取浏览器的类型
//自动设置不同的编码方式
String ua = request.getHeader("User-Agent");
// 判断是否是火狐浏览器
if (ua.contains("Firefox")) {
// 使用下面的格式进行 BASE64 编码后
String attachmentFile = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode(fileName.getBytes("utf-8")) + "?=";
// 设置到响应头中
response.setHeader("Content-Disposition", attachmentFile);
} else {
// 把中文名进行 UTF-8 编码操作。
String attachmentFile = "attachment; fileName=" + URLEncoder.encode(fileName, "UTF-8");
// 然后把编码后的字符串设置到响应头中
response.setHeader("Content-Disposition", attachmentFile);
}
//4.输出字节流数据到浏览器
IOUtils.copy(is, os);
//3. 关闭资源
os.close();
is.close();
}
}
浏览器测试如下:
image-20210109142801275
相关文章
- 分析了7500w+GitHub代码仓库 哪门语言热度最高?
- 兄弟,这种思路讲解HDFS你肯定没见过,快速入门Hadoop必备
- 大数据架构详解:从数据获取到深度学习
- 一则关于大数据的要闻:大数据生于2006,卒于2019!这是真的吗?
- 企业在机器学习中容易犯的五个错误
- 为什么说,大数据与行业专家是“共生”关系?
- 数据分析入门经典问题:你两个朋友同一天过生日的概率有多大?
- 大数据和人工智能:3个真实世界的用例
- 大数据干货分享:大数据集群的自动化运维实现思路
- 容器堆栈须知的八个要素
- 最受世界500强企业青睐的编程语言,竟是他们?
- 需要考虑的工业4.0大数据挑战
- 为什么只靠大数据不能加快企业的决策
- 为什么数据科学的专业认证越来越重要?
- 春运抢票大作战:传说中的抢票神器真的存在吗?
- 人工智能和自动化改善过程挖掘的6种方法
- 云计算数据仓库的下一步是什么
- 如何从企业IT人员成长为优秀的数据分析师?
- 10分钟零基础就可搞懂的Hadoop架构原理,阿里架构师详解
- PHP发送HTTP请求的6种方法,知道4种算你牛!