Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >22. Servlet入门 - 文件下载案例

22. Servlet入门 - 文件下载案例

作者头像
Devops海洋的渔夫
发布于 2021-11-12 01:26:33
发布于 2021-11-12 01:26:33
40700
代码可运行
举报
文章被收录于专栏:Devops专栏Devops专栏
运行总次数:0
代码可运行

22. Servlet入门 - 文件下载案例

案例-完成文件下载

1.需求分析

  • 创建文件下载的列表的页面,点击列表中的某些链接,下载文件.

img/

2.文件下载分析

2.1什么是文件下载

服务器上已经存在的文件,输出到客户端浏览器.

说白了就是把服务器端的文件拷贝一份到客户端, 文件的拷贝---> 流(输入流和输出流)的拷贝

2.2文件下载的方式
  • 第一种:超链接方式(不推荐) 链接的方式:直接将服务器上的文件的路径写到href属性中.如果浏览器不支持该格式文件,那么就会提示进行下载, 如果 浏览器支持这个格式(eg: png, jpg....)的文件,那么直接打开,不再下载了
  • 第二种:手动编码方式(推荐) 手动编写代码实现下载.无论浏览器是否识别该格式的文件,都会下载.

3.思路分析

3.1超链接方式
  1. 准备下载的资源(文件)
  2. 编写一个下载页面
  3. 在这个页面上定义超链接,指定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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//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 ,那么该怎么设置下载的文件名呢?

我们可以通过设置响应头来处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
response.setHeader("Content-Disposition","attachment;filename="+fileName);

实现代码如下:

image-20210109141354809

浏览器测试如下:

image-20210109141422338

image-20210109141452948

我们可以看到,如果下载的文件为中文内容,那么文件名则无法正常显示。

5. 解决下载中文的文件名乱码问题

在上面我们下载中文名称的文件的时候,会出现乱码的情况,那么该怎么解决呢?

其实还是编码格式的问题,只要设置编码格式即可。下面来看看如果设置。

中文文件在不同的浏览器中编码方式不同:火狐是Base64编码, 其它浏览器(谷歌)是URL的utf-8编码

image-20210109142711952

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【深度学习】MLP/LeNet/AlexNet/GoogLeNet/ResNet在三个不同数据集上的分类效果实践
v1:引入了Inception结构,并使用1x1卷积和来压缩通道数(减少参数量。Inception作用:代替人工确定卷积层中的过滤器类型或者确定是否需要创建卷积层和池化层,即:不需要人为的决定使用哪个过滤器,是否需要池化层等,由网络自行决定这些参数,可以给网络添加所有可能值,将输出连接起来,网络自己学习它需要什么样的参数。
zstar
2022/06/14
1.3K0
【深度学习】MLP/LeNet/AlexNet/GoogLeNet/ResNet在三个不同数据集上的分类效果实践
TensorFlow 2.0 - Checkpoint 保存变量、TensorBoard 训练可视化
文章目录 1. Checkpoint 保存变量 2. TensorBoard 训练过程可视化 学习于:简单粗暴 TensorFlow 2 1. Checkpoint 保存变量 tf.train.Checkpoint 可以保存 tf.keras.optimizer 、 tf.Variable 、 tf.keras.Layer 、 tf.keras.Model path = "./checkp.ckpt" # 建立一个 checkpoint mycheckpoint = tf.train.Checkpoin
Michael阿明
2021/02/19
1.1K0
TensorFlow 2.0 - Checkpoint 保存变量、TensorBoard 训练可视化
TensorFlow之CNN
CNN 就是convolutional neural network, 也就是卷积神经网络,是一种类似于人类或动物视觉系统结构的人工神经网络,包含一个或多个卷积层(convolutional layer)、池化层(pooling layer)和全连接层(fully-connected layer),总之,这些年他很火。
Ed_Frey
2020/12/30
3990
用Docker部署TensorFlow Serving服务
参考: https://tf.wiki/zh_hans/deployment/serving.html# https://tensorflow.google.cn/tfx/serving/docker
Michael阿明
2021/02/19
5550
用Docker部署TensorFlow Serving服务
RNN预测行人运动轨迹
数据集来源自[1],每个数据目录包含一个pixel_pos.csv文件,它的文件格式如下:
YoungTimes
2022/04/28
2.9K0
RNN预测行人运动轨迹
TensorFlow 2.0 - CNN / 预训练 / RNN
文章目录 1. CNN 卷积神经网络 2. 预训练模型 3. RNN 循环神经网络 学习于:简单粗暴 TensorFlow 2 1. CNN 卷积神经网络 卷积神经网络,卷积后尺寸计算 tf.keras.layers.Conv2D, tf.keras.layers.MaxPool2D # CNN 模型 class myCNN(tf.keras.Model): def __init__(self): super().__init__() self.conv1 = tf
Michael阿明
2021/02/19
5370
TensorFlow 2.0 - Keras Pipeline、自定义Layer、Loss、Metric
文章目录 1. Keras Sequential / Functional API 2. 自定义 layer 3. 自定义 loss 4. 自定义 评估方法 学习于:简单粗暴 TensorFlow 2 1. Keras Sequential / Functional API tf.keras.models.Sequential([layers...]),但是它不能表示更复杂的模型 mymodel = tf.keras.models.Sequential([ tf.keras.layers.Flat
Michael阿明
2021/02/19
1.1K0
TensorFlow还是PyTorch?哪一个才更适合编写深度神经网络?
编程实现神经网络的最佳框架是什么?TensorFlow还是PyTorch?我的回答是:别担心,你从哪一个入门,你选择哪一个并不重要,重要的是自己动手实践!下面我们开始吧!
deephub
2020/05/09
2.1K0
TensorFlow还是PyTorch?哪一个才更适合编写深度神经网络?
干货 | TensorFlow 2.0 模型:Keras 训练流程及自定义组件
在上一篇文章中,我们介绍了循环神经网络的建立方式。本来接下来应该介绍 TensorFlow 中的深度强化学习的,奈何笔者有点咕,到现在还没写完,所以就让我们先来了解一下 Keras 内置的模型训练 API 和自定义组件的方法吧!本文介绍以下内容:
AI研习社
2019/10/22
3.3K0
Tensorflow日常随笔(一)
TensorFlow is an end-to-end open source platform for machine learning
XianxinMao
2021/07/31
2610
Tony老师解读Kaggle Twitter情感分析案例
今天Tony老师给大家带来的案例是Kaggle上的Twitter的情感分析竞赛。在这个案例中,将使用预训练的模型BERT来完成对整个竞赛的数据分析。
矩池云
2020/04/10
1.1K0
Tony老师解读Kaggle Twitter情感分析案例
基于TensorFlow Eager Execution的简单神经网络模型
Eager Execution是TensorFlow(TF)中一种从头开始构建深度学习模型的好方法。它允许您构建原型模型,而不会出现TF常规使用的图形方法所带来的麻烦。
代码医生工作室
2019/06/21
7780
基于TensorFlow Eager Execution的简单神经网络模型
TensorFlow 2.0 快速入门指南:第二部分
在本节中,我们将首先看到 TensorFlow 在监督机器学习中的许多应用,包括线性回归,逻辑回归和聚类。 然后,我们将研究无监督学习,特别是应用于数据压缩和去噪的自编码。
ApacheCN_飞龙
2023/04/23
5690
斯坦福tensorflow教程-tensorflow 实现逻辑回归03_logreg_placeholder.py实验结果utils.py
03_logreg_placeholder.py 代码有详细的注释: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2018-06-05 17:00:43 # @Author : quincy # @Email :yanqiang@cyou-inc.com import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import numpy as np import tensorflo
致Great
2018/06/06
7300
生成型对抗性网络介绍与实现原理
如何无中生有是AI领域研究的重点。原有神经网络大多是对已有问题的识别和研究,例如让神经网络学会识别图片中的动物是猫还是狗,随着研究的进一步深入,目前能够做到让网络不但能识别图片中的物体,还能让它学会如何创造图片中的物体,具备”创造性“让AI技术的应用价值大大提升。
望月从良
2020/02/26
3700
TensorFlow2.0(9):神器级可视化工具TensorBoard
TensorBoard是TensorFlow中的又一神器级工具,想用户提供了模型可视化的功能。我们都知道,在构建神经网络模型时,只要模型开始训练,很多细节对外界来说都是不可见的,参数如何变化,准确率怎么样了,loss还在减小吗,这些问题都很难弄明白。但是,TensorBoard通过结合web应用为我们提供了这一功能,它将模型训练过程的细节以图表的形式通过浏览器可视化得展现在我们眼前,通过这种方式我们可以清晰感知weight、bias、accuracy的变化,把握训练的趋势。
统计学家
2019/12/25
3.7K0
TensorFlow 2.0 - tf.data.Dataset 数据预处理 & 猫狗分类
项目及数据地址:https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/overview
Michael阿明
2021/02/19
2.5K0
TensorFlow 2.0 - tf.data.Dataset 数据预处理 & 猫狗分类
Tensorflow之基础篇
终于有点时间学一下之前碎碎念的TensorFlow,主要代码为主,内容来源于《简明的TensorFlow2》作者 李锡涵 李卓恒 朱金鹏,人民邮电出版社2020.9第1版。
Ed_Frey
2020/12/30
8510
Tensorflow之基础篇
tf42:tensorflow多GPU训练
MachineLP的Github(欢迎follow):https://github.com/MachineLP
MachineLP
2019/05/26
7800
pointnet训练文件train.py注释
发布者:全栈程序员栈长,转转请注明出处:https://javaforall.cn/2169.html原文链接:
全栈程序员站长
2021/04/07
6320
相关推荐
【深度学习】MLP/LeNet/AlexNet/GoogLeNet/ResNet在三个不同数据集上的分类效果实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验