servlet中实现文件下载操作

这里是servlet中的代码,用来实现文件下载的逻辑实现,难点在于如何让浏览器弹出下载选项以及如何解决中文文件名在浏览器里不显示的问题。
针对第一个问题,需要用到content-disposition来处理响应头,针对第二个问题,是在网上找了一个工具类,针对不同的浏览器有不同的实现。
目录结构如下:
servlet中实现文件下载操作_第1张图片
这是DownloadServlet类中的代码实现

package com.google.web.download;

import com.google.web.utils.DownLoadUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
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;

/**
 * @author Yuechao Yang
 * @version 2019-05-15-21:28
 */
@WebServlet(name = "DownloadServlet", urlPatterns = "/downloadServlet")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取请求参数,即文件名称
        String filename = request.getParameter("filename");
        //2.使用字节输入流加载文件进内存
        //2.1找到文件真实(服务器)路径
        ServletContext servletContext = this.getServletContext();
        String realPath = servletContext.getRealPath("/img/" + filename);
        //2.2用字节流关联
        FileInputStream fis = new FileInputStream(realPath);//输入流

        //3.设置response的响应头,起到的作用是跳出让下载保存
        //3.1设置响应头类型 content-type
        String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
        response.setHeader("content-type",mimeType);

        //解决中文乱码问题
        //1.获取user-agent请求头
        String agent = request.getHeader("user-agent");

        //2.使用工具类方法编码文件名即可
        filename  = DownLoadUtils.getFileName(agent, filename);

        //3.2设置响应头打开方式 content-disposition      千万不能写错
        response.setHeader("content-disposition", "attachment;filename="+ filename);


        //4.将输入流的数据写出到输出流中
        ServletOutputStream sos = response.getOutputStream();//首先需要一个输出流
        byte[] buff = new byte[1024 * 8];//其次需要一个字节数组作为缓冲区
        int len = 0;    //代表读到的字节的个数
        while ((len = fis.read(buff))!= -1){//把输入流中的字节读到缓冲区,并且把读到的个数赋值给len,如果没有读取到文件的末尾
            sos.write(buff, 0, len);//输出流不停的往外写,因为是字节流,所以不用刷新。这里掌握不充分,知识点都不记得了
        }
        fis.close();
    }

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

接下来是在网上找的工具类。DownloadUtils类

package com.google.web.utils;

import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;


public class DownLoadUtils {

    public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

download.html中的代码




    
    download


    
        图片1
    
    
图片1

经测试,在chrome中点击第二个图片1时,浏览器会直接下载而不弹出询问界面。
servlet中实现文件下载操作_第2张图片
而在ie浏览器中点击第二个会显示404.
该ie的版本是
servlet中实现文件下载操作_第3张图片

你可能感兴趣的:(javaEE)