JavaWeb 文件下载功能

文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端,所以文件下载需要IO技术将服务器端的文件读取到,然后写到response缓冲区中,然后再下载到个人客户端。

1. 文件名 - 接受前端发来的文件名

获取到前端页面发送过来的要下载的文件的名字

String filenameValue = req.getParameter("filename");

2. ServletContext域 - 获取到ServletContext域对象

后面将调用此对象的一系列方法,用于获取文件路径、文件MimeType,并设置文件输出类型

ServletContext servletContext = req.getServletContext();  //获取到ServletContext域对象

3. 文件路径 - 获取指定文件在web项目中的路径

通过获取到ServletContext域对象的getRealPath()方法,读取download目录下文件的绝对路径

注意:download目录必须放在webContent目录下面,否则可能会找不到,导致报异常,在读取资源的时候,项目demo会直接去查找webContent下面的文件和文件夹

String realPath = servletContext.getRealPath("download/"+filenameValue);  //获取到要下载文件在web项目中的绝对路径

4. 文件MimeType - 获取文件的MimeType类型

通过获取到的 ServletContext 域对象的 getMimeType() 方法,获取到文件MimeType

MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。

MIME 协议指示 MIME 用户代理如何显示附加的文件。

MIME 参考手册:http://www.w3school.com.cn/media/media_mimeref.asp

告知浏览器文件的类型:response.setContentType(文件的MIME类型);

String mimeType = servletContext.getMimeType(filenameValue);  //获取到要下载文件的mimeType类型

5. 输出类型 - 设置文件的输出类型

根据之前获取到的文件MimeType,然后通过 Response 域对象的 setContentType() 方法,设置文件的输出类型

resp.setContentType(mimeType);  //设置文件的输出类型

6. 设置响应头 - 确定文件是内嵌或弹出下载框

通过 Response 域对象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法设置响应头

Content-Disposition(内容处置/处理)

是 MIME 协议的扩展,Content-Disposition 可以控制用户请求所得的内容存为一个文件时提供一个默认的文件名

inline 和 attachment:文件直接在浏览器上显示或者在访问时弹出文件下载对话框。

inline 表示:内嵌显示,文本和图片都可以解析,但对于文件或者视频会自动去调用成attachment,因此可以直接使用inline

attachment:弹出下载框,因为attachment是让文件以附件的形式打开,因此会调用下载,但此下载的功能并没有提示

//设置输出(下载)的文件的默认文件名为filenameValue的值,inline表示内嵌文本和图片,文件和视频会自动调用成attachment

resp.setHeader("Content-Disposition", "inline;filename="+filenameValue);

7. 执行输出(下载) - IO流

7.1 通过 new,创建字节输入流 FileInputStream,读取文件

7.2 通过Response域,创建Servlet的输出流,输出文件

FileInputStream fileInputStream = new FileInputStream(realPath);

ServletOutputStream  outputStream = resp.getOutputStream();

int b=0;

byte[] by = new byte[1024*8];

while ((b=fileInputStream.read(by))!=-1) {

outputStream.write(by, 0, b);

}

outputStream.flush();

fileInputStream.close();

outputStream.close();  //关流,response获得流会自动关闭,因此也可以不用手动关

功能实现代码

Java 代码 - /demo/src/com/Download.java

package com;

import java.io.FileInputStream;

import java.io.IOException;

import java.net.URLEncoder;

import javax.servlet.ServletConfig;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class Download extends HttpServlet{

@Override

public void init(ServletConfig config) throws ServletException {

/**重写了Servlet的init(ServletConfig config)方法后一定要记得调用父类的init方法,

* 否则在service/doGet/doPost方法中使用getServletContext()方法获取ServletContext对象时

* 就会出现java.lang.NullPointerException异常

* */

super.init(config);

}

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doPost(req, resp);

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

/**1. 接受前端页面发送过来的文件名字

* 获取到前端页面发送过来的要下载的文件的名字

* */

String filenameValue = req.getParameter("filename");

//---------------------

//      filenameValue = URLEncoder.encode(filenameValue, "gbk");

/**2. 获取到ServletContext域对象

* 后面将调用此对象的一系列方法,用于获取文件路径、文件MimeType、文件输出类型

* */

ServletContext servletContext = req.getServletContext();  //获取到ServletContext域对象

/**3. 获取指定文件在web项目中的路径

* 通过获取到ServletContext域对象的getRealPath()方法,读取download目录下文件的绝对路径

* download目录必须放在webContent目录下面,否则可能会找不到,导致报异常,

* 在读取资源的时候,项目demo会直接去查找webContent下面的文件和文件夹

* */

String realPath = servletContext.getRealPath("download/"+filenameValue);  //获取到要下载文件在web项目中的绝对路径

/**4. 获取到文件MimeType

* 通过获取到的ServletContext域对象的getMimeType()方法,获取到文件MimeType

* MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。

* MIME 协议指示 MIME 用户代理如何显示附加的文件。

* MIME 参考手册:http://www.w3school.com.cn/media/media_mimeref.asp

* */

String mimeType = servletContext.getMimeType(filenameValue);  //获取到要下载文件的mimeType类型

/**5. 设置文件的输出类型

* Response域对象的setContentType()方法,设置文件的输出类型

* */

resp.setContentType(mimeType);  //设置文件的输出类型

/**6. 设置响应头,确定文件是内嵌或弹出下载框

* 通过 Response 域对象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法设置响应头,

* Content-Disposition(内容处置/处理) :

*      是 MIME 协议的扩展,Content-Disposition 可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,

* inline 和 attachment :

*      文件直接在浏览器上显示或者在访问时弹出文件下载对话框。

*      inline 表示:内嵌显示,文本和图片都可以解析,但对于文件或者视频会自动去调用成attachment,因此可以直接使用inline

*      attachment:弹出下载框

* URLEncoder 对象,将在响应回去的头,里面所代码filename的编码格式,转换为与客户端的一致的编码格式

*      URLEncoder.encode(filenameValue,"utf-8"); 将Response响应到浏览器客户端为filenameValue的文件名,转变为utf-8的编码格式

*/

resp.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filenameValue,"utf-8"));  //设置输出(下载)的文件的默认文件名为filenameValue的值,inline表示内嵌文本和图片

/**7. 输出文件(下载文件)

* 7.1 通过 new,创建字节输入流 FileInputStream,读取文件

* 7.2 通过Response域,创建Servlet的输出流,输出文件

* */

FileInputStream fileInputStream = new FileInputStream(realPath);

ServletOutputStream  outputStream = resp.getOutputStream();

int b=0;

byte[] by = new byte[1024*8];

while ((b=fileInputStream.read(by))!=-1) {

outputStream.write(by, 0, b);

}

outputStream.flush();

fileInputStream.close();

outputStream.close();  //关流,response获得流会自动关闭,因此也可以不用手动关

}

}

前端页面 jsp 代码 - /demo/WebContent/download.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

String path=request.getContextPath();

String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE html>

<html>

<head>

<!-- <base> 标签为页面上的所有链接规定默认地址或默认目标。 -->

<base href="<%=basePath%>">

<meta charset="UTF-8">

<title>文件下载</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

</head>

<body>

<a href="download?filename=JDBC连接主流数据库.txt">点击下载 文件</a> <br/>

<a href="download?filename=0413102708.avi">点击下载 视频</a>

</body>

</html>

web.xml - /demo/WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

<display-name>demo</display-name>

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.htm</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<context-param>

<param-name>ServletContextName</param-name>

<param-value>ServletContextValue</param-value>

</context-param>

<servlet>

<servlet-name>Download</servlet-name>

<servlet-class>com.Download</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>Download</servlet-name>

<url-pattern>/download</url-pattern>

</servlet-mapping>

</web-app>

下载文件出现中文乱码和不显示文件名的情况

在有些情况下,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,原因是不同的浏览器默认对下载文件的编码方式不同,比如ie是UTF-8编码方式,而火狐浏览器是Base64编码方式。

/**URLEncoder 对象,将在响应回去的头,里面所代码filename的编码格式,转换为与客户端的一致的编码格式

*  URLEncoder.encode(filenameValue,"utf-8");

*      将Response响应到浏览器客户端为filenameValue的文件名,转变为utf-8的编码格式

* */

resp.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filenameValue,"utf-8"));

详细配置信息可以参考这篇文章:http://blog.ncmem.com/wordpress/2019/08/28/java%e6%89%b9%e9%87%8f%e4%b8%8b%e8%bd%bd/

java+web+批量下载文件的更多相关文章

  1. web批量下载文件到本地

    JavaWeb 文件下载功能 文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端,所以文件下载需要IO技术将服务器端的文件读取到,然后写到response缓冲区中,然后再下载到个人客户端. 1 ...

  2. Java Web之下载文件

    下载的文件,不能随便的被访问,放在外面的文件夹肯定不行,url一敲就能访问了,所以我们要放在WEB-INF文件夹里面,WEB-INF文件夹只有Servlet才能访问,我们新建一个文件夹,叫downlo ...

  3. java多线程批量下载文件

    多线程下载文件 平时开发中有时会用到文件下载,为了提高文件的下载速率,采用多线程下载能够达到事半功倍的效果: package test; /** * 文件下载类 * @author luweichen ...

  4. C#使用ICSharpCode.SharpZipLib压缩后进行web批量下载文件

    参考:http://blog.csdn.net/kongwei521/article/details/51167903#

  5. JAVA Web 之 struts2文件上传下载演示(二)(转)

    JAVA Web 之 struts2文件上传下载演示(二) 一.文件上传演示 详细查看本人的另一篇博客 http://titanseason.iteye.com/blog/1489397 二.文件下载 ...

  6. JAVA Web 之 struts2文件上传下载演示(一)(转)

    JAVA Web 之 struts2文件上传下载演示(一) 一.文件上传演示 1.需要的jar包 大多数的jar包都是struts里面的,大家把jar包直接复制到WebContent/WEB-INF/ ...

  7. java/resteasy批量下载存储在阿里云OSS上的文件,并打包压缩

    现在需要从oss上面批量下载文件并压缩打包,搜了很多相关博客,均是缺胳膊少腿,要么是和官网说法不一,要么就压缩包工具类不给出 官方API https://help.aliyun.com/documen ...

  8. Java批量下载文件并zip打包

    客户需求:列表勾选需要的信息,点击批量下载文件的功能.这里分享下我们系统的解决方案:先生成要下载的文件,然后将其进行压缩,生成zip压缩文件,然后使用浏览器的下载功能即可完成批量下载的需求.以下是zi ...

  9. 批量下载文件web

    最近需要这个所以写了一个例子一般批量下载由以下步骤组成: 1.确定下载的源文件位置 2.对文件进行打包成临时文件,这里会用到递归调用,需要的嵌套的文件夹进行处理,并返回文件保存位置 3.将打包好的文件 ...

随机推荐

  1. vultr vps 开启BBR加速 (CentOS 7)

    上个月买的vultr的vps 感觉看视频还是比较慢的 于是上网找教程开启BBR加速 在这里记录一下 以后可能会用到 BBR 是 Google 提出的一种新型拥塞控制算法,可以使 Linux 服务器显著 ...

  2. Git 的这个神技,学会爽歪歪~

    现在大多数公司都有 GIT 来管理代码版本控制了,既然用到 GIT,相信大家都接触过 Github.Gitlab.Gitee 这些远程仓库,或者是公司内部自行搭建的 GIT 仓库. 当用到 SSH 方 ...

  3. dp入门题(数塔)

    http://acm.hdu.edu.cn/showproblem.php?pid=2084 题意: 7 3  8 8 1   0 2      7 4   4 4 5 2    6     5 在上 ...

  4. 运维nslookup语法

    nslookup 查询域名DNS信息的工具 补充说明 nslookup命令 是常用域名查询工具,就是查DNS信息用的命令. nslookup4有两种工作模式,即“交互模式”和“非交互模式”.在“交互模 ...

  5. 运维ipvsadm配置负载均衡2

    一.什么是lvs1.lvs的定义LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统.是由章文嵩博士开发的一款开源软件,1998年5月发布,是中 ...

  6. python中逐行打印

    方法一:readline函数 f = open("./code.txt") # 返回一个文件对象 line = f.readline() # 调用文件的 readline()方法 ...

  7. TypeError: esri.layers.WMSLayer is not a constructor

    最近加载wms地图后,总是报这个错误,因为错误,导致后续的代码无法加载,导致无法功能使用. 原因是,由于方法公用,有的新功能在使用时,引用依赖包时,未引用完整,导致加载此处加载wms图层的时候, 报此 ...

  8. ms17_0199样本测试

    一大早就各种消息弹框,于是就来测试一波 https://github.com/nixawk/metasploit-framework/blob/8ab0b448fdce15999f155dfd7b22 ...

  9. Windows下搭建Nacos及Seata

    一.简介 本文主要描述Nacos及Seata在Windows环境下环境搭建 下载相关软件: Nacos-1.1.4 Seata-0.9.0 二.安装 2.1安装Nacos 解压nacos-server ...

  10. String与C风格字符串转换

    String字符串转换为C风格字符串需要利用string类的成员函数c_str().而C风格字符串转换转换为string字符串可以直接利用运算符=.首先介绍c_str()函数原型: const val ...