前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >22. Servlet入门 - 文件下载案例

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

作者头像
Devops海洋的渔夫
发布2021-11-12 09:26:33
3810
发布2021-11-12 09:26:33
举报
文章被收录于专栏:Devops专栏

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
复制
<!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
复制
@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
复制
@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
复制
//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
复制
response.setHeader("Content-Disposition","attachment;filename="+fileName);

实现代码如下:

image-20210109141354809

浏览器测试如下:

image-20210109141422338

image-20210109141452948

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

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

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

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

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

image-20210109142711952

代码语言:javascript
复制
@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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 22. Servlet入门 - 文件下载案例
    • 案例-完成文件下载
      • 1.需求分析
      • 2.文件下载分析
      • 3.思路分析
      • 4.代码实现
      • 5. 解决下载中文的文件名乱码问题
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档