Java文件下载(简易版)

Java文件下载

创建html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="/downloadServlet?filename=1.jpg" >图片下载</a>
<a href="/downloadServlet?filename=哈哈啊.jpg" >中文名称图片下载</a>
<a href="/img/1.jpg" >图片下载2</a>

</body>
</html>

创建Servlet

package com.citicbank.fileDownload;

import com.citicbank.utils.DownLoadUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

@WebServlet("/downloadServlet")
public class DownServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1.根据请求参数,获得文件类型
        String filename = request.getParameter("filename");
        //2. 获取路径
        ServletContext servletContext = request.getServletContext();
        String realPath = servletContext.getRealPath("/img/"+filename);
        // 3.文件读取,字节流
//        ServletInputStream inputStream = request.getInputStream(); 为什么不能用getInputStream
        FileInputStream inputStream = new FileInputStream(realPath);

        // 4.设置响应头
        String mimeType = servletContext.getMimeType(filename);// 获取文件的MIME类型
        response.setHeader("content-type", mimeType);

        // 5.解决中文乱码问题
//        1、获取user-agent请求头
//        String agent = request.getHeader("user-agent");
//        System.out.println(agent);
//        2、使用工具类方法编码文件名即可
//        String fileName = DownLoadUtils.getFileName3(agent, filename);
//        response.setCharacterEncoding("UTF-8");


        //        服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,
//          比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,
//          就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment(附件):
//        response.setHeader("content-disposition", "attachment;filename="+filename);
        response.setHeader("content-disposition", "attachment;filename="+(new String(filename.getBytes("UTF-8"), "ISO8859-1")));

        // 6.文件送入到输出流
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while ((len = inputStream.read(bytes))!=-1){
            outputStream.write(bytes, 0, len);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

遇到的问题

  1. 如果文件放在web目录下创建的子文件夹,比如img,在使用servletContext.getRealPath的时候记得加上img,即String realPath = servletContext.getRealPath("/img/"+filename);
  2. 设置响应头,让浏览器弹出下载框

Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。当 Internet Explorer接收到头时,它会激活文件下载对话框,它的文件名框自动填充了头中指定的文件名。(请注意,这是设计导致的;无法使用此功能将文档保存到用户的计算机上,而不向用户询问保存位置。)
服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment:
Response.AppendHeader("Content-Disposition","attachment;filename=FileName.txt");
(备注:这样浏览器会提示保存还是打开,即使选择打开,也会使用相关联的程序比如记事本打开,而不是IE直接打开了。)

  1. 中文文件名支持
    网上很多解决方案都不好使,其实就是一句话的事情
    response.setHeader("content-disposition", "attachment;filename="+(new String(filename.getBytes("UTF-8"), "ISO8859-1")));

4. getInputStream主要是用来接收post提交上来的表单

参考

  1. java文件下载中Content-disposition的定义
  2. 解决java 文件名中文,下载时文件名乱码
  3. 使用request.getInputStream() 获取POST数据

版权声明:本文为weixin_44191286原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。