利用response对象实现下载文件功能

HttpServletResponse对象继承了ServletResponse接口,下面利用response对象实现下载的功能。

单个文件的下载

package com.dongmu.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

public class ResponseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        String realpath = getServletContext().getRealPath("/");
//D:\word文档\电子版练习册\JAVA\02-WEB前端\kuangstudy\response\target\response-1.0-SNAPSHOT\
//这个getRealPath方法可以获得项目的绝对路径,
//        System.out.println(realpath);
        String filename = "壁纸.jpg";
		//设置文件头:最后一个参数是设置下载文件名        
        response.setHeader("Content-Disposition", "attachment;fileName="+filename);
        FileInputStream inputStream = new FileInputStream(realpath+"static/17.jpg");
        byte[] bytes = new byte[1024];
        int len =0;
        //用response对象获取输出流
        ServletOutputStream outputStream = response.getOutputStream();
        while ((len=inputStream.read(bytes))>0){
            outputStream.write(bytes,0,len);
        }
        inputStream.close();
        outputStream.close();
    }
}

        String realpath = getServletContext().getRealPath("/");
获得的是:D:\word文档\电子版练习册\JAVA\02-WEB前端\kuangstudy\response\target\response-1.0-SNAPSHOT\
这个getRealPath方法可以获得项目的绝对路径,可以看一下我项目的目录结构,它所得到的就是项目打包之后webapp对应的路径。

在这里插入图片描述

但是这里有一个问题,就是我的文件名是中文,那么下载的时候就出现无法获取的现象,如下图

在这里插入图片描述

解决方案:
把代码改成:response.setHeader("Content-Disposition", "attachment;fileName="+ URLEncoder.encode(filename,"utf-8"));

在这里插入图片描述

原因:URLEncoder编码
客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文。
而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址,
将网址中的非ASCII码内容转换成可以传输的字符
编码原理:
1、将需要转换的内容(ASCII码形式之外的内容),用十六进制表示法转换出来,并在之前加上%开头
eg:  0x9c  URLEncoder --> %9c
2、内容中的空格‘ ’ ,全部用+代替
3、注:与Hex不同,Hex是将所有的字符转换为16进制表示,而URLEncoder是将ASCII码集之外的转换为%加上相应的16进制,而ASCII码集内的字符不进行处理

多个文件的打包下载

前端测试html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/download">
    请输入下载文件的地址:<br>
    <input type="text" name="filePath">
    <br>
    <input type="submit" value="下载">
</form>

<br>
<hr>
<br>
<form action="http://localhost:8080/downloads">
    请输入下载多个文件的地址:<br>
    <input type="text" name="filePath">
    <br>
    <input type="text" name="filePath">
    <br>
    <input type="submit" value="下载">
</form>
</body>
</html>

后端实现

@RequestMapping("/downloads")
    public void downloads(@RequestParam("filePath") String[] filePaths, HttpServletResponse response){
        String zipName = "打包文件.zip";
        ArrayList<String> fileList = new ArrayList<>(Arrays.asList(filePaths));
        ZipOutputStream zos = null;

        try {
            response.setContentType("application/x-download ");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName, "UTF-8"));
            zos = new ZipOutputStream(response.getOutputStream());
            downloadTolocal(zos, fileList);
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 打包压缩
    private void downloadTolocal(ZipOutputStream zos, ArrayList<String> fileList) throws IOException {
        InputStream input = null;
        for (String filePath : fileList) {
            File file = new File(filePath);
            // 一个文件对应一个ZipEntry
            ZipEntry zipEntry = new ZipEntry(file.getName());
            input = new FileInputStream(file);
            zos.putNextEntry(zipEntry);
            IOUtils.copy(input, zos);
        }
        zos.close();
        input.close();
    }

在这里插入图片描述

在这里插入图片描述
实验成功

推荐阅读
推荐阅读
推荐阅读

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北海冥鱼未眠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值