IT兄弟连 JavaWeb教程 文件下载技术
● 列出提供下载的文件资源
我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件。
ListFileServlet的代码如下:
package com.xdl.servlet;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 获取上传文件的目录
String uploadFilePath = this.getServletContext().
getRealPath("/WEB-INF/ upload");
// 存储要下载的文件名
Map<String, String> fileNameMap = new HashMap<String, String>();
// 递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中
listfile(new File(uploadFilePath), fileNameMap);
// File既可以代表一个文件也可以代表一个目录
// 将Map集合发送到listfile.jsp页面进行显示
request.setAttribute("fileNameMap", fileNameMap);
request.getRequestDispatcher("/listfile.jsp").
forward(request, response);
}
public void listfile(File file, Map<String, String> map) {
// 如果file代表的不是一个文件,而是一个目录
if (!file.isFile()) {
// 列出该目录下的所有文件和目录
File files[] = file.listFiles();
// 遍历files[]数组
for (File f : files) {
// 递归
listfile(f, map);
}
} else {
/**
* 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的
*/
String realName = file.getName().substring(
file.getName().indexOf ("_") + 1);
// file.getName()得到的是文件的原始名称,这个名称是唯一的,
// 因此可以作为key,realName是处理过后的名称,有可能会重复
map.put(file.getName(), realName);
}
}
}
这里介绍一下ListFileServlet中listfile方法,listfile方法是用来列出目录下的所有文件的,listfile方法内部用到了递归,在实际开发当中,我们肯定会在数据库创建一张表,里面会存储上传的文件名以及文件的具体存放目录,我们通过查询表就可以知道文件的具体存放目录,是不需要用到递归操作的,这个例子是因为没有使用数据库存储上传的文件名和文件的具体存放位置,而上传文件的存放位置又使用了散列算法打散存放,所以需要用到递归,在递归时,将获取到的文件名存放到从外面传递到listfile方法里面的Map集合当中,这样就可以保证所有的文件都存放在同一个Map集合当中。
在web.xml文件中配置ListFileServlet。
<servlet>
<servlet-name>ListFileServlet</servlet-name>
<servlet-class>com.xdl.servlet.ListFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListFileServlet</servlet-name>
<url-pattern>/list</url-pattern>
</servlet-mapping>
● 展示下载文件的listfile.jsp页面,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>兄弟连IT教育</title>
</head>
<body>
<c:forEach var="me" items="${fileNameMap}">
<c:url value="/download" var="downurl">
<c:param name="filename" value="${me.key}"></c:param>
</c:url>
${me.value}<a href="${downurl}">下载</a>
<br />
</c:forEach>
</body>
</html>
访问ListFileServlet,就可以在listfile.jsp页面中显示提供给用户下载的文件资源,如图25所示。

图25 listfile.jsp页面
● 实现文件下载
编写一个用于处理文件下载的Servlet,DownloadServlet的代码如下:
package com.xdl.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 得到要下载的文件名
String fileName = request.getParameter("filename");
// 上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
String fileSaveRootPath =
this.getServletContext().getRealPath ("/WEB-INF/upload");
// 通过文件名找出文件的所在目录
String path = findFileSavePathByFileName(fileName, fileSaveRootPath);
// 得到要下载的文件
File file = new File(path + "\\" + fileName);
// 如果文件不存在
if (!file.exists()) {
request.setAttribute("message", "您要下载的资源已被删除!!");
request.getRequestDispatcher("/message.jsp").
forward(request, response);
return;
}
// 处理文件名
String realname = fileName.substring(fileName.indexOf("_") + 1);
// 设置响应头,控制浏览器下载该文件
response.setHeader("content-disposition",
"attachment;filename=" + URLEncoder.
encode(realname, "UTF-8"));
// 读取要下载的文件,保存到文件输入流
FileInputStream in = new FileInputStream(path + "\\" + fileName);
// 创建输出流
OutputStream out = response.getOutputStream();
// 创建缓冲区
byte buffer[] = new byte[1024];
int len = 0;
// 循环将输入流中的内容读取到缓冲区当中
while ((len = in.read(buffer)) > 0) {
// 输出缓冲区的内容到浏览器,实现文件下载
out.write(buffer, 0, len);
}
// 关闭文件输入流
in.close();
// 关闭输出流
out.close();
}
public String findFileSavePathByFileName
(String filename, String saveRootPath) {
int hashcode = filename.hashCode();
int dir1 = hashcode & 0xf;
int dir2 = (hashcode & 0xf0) >> 4;
String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;
File file = new File(dir);
if (!file.exists()) {
// 创建目录
file.mkdirs();
}
return dir;
}
}
● 在web.xml文件中配置DownloadServlet。
<servlet>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.xdl.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
再次访问ListFileServlet,就可以在listfile.jsp页面中点击下载开始下载资源,如图26所示。

图26 下载文件

图27 下载文件成功
从运行结果可以看到,我们的文件下载功能已经可以正常下载文件了。
IT兄弟连 JavaWeb教程 文件下载技术的更多相关文章
- IT兄弟连 JavaWeb教程 AJAX的技术构成
Ajax并不是新的技术,而是之前技术的整合,其中包括JavaScript.HTML.CSS.DOM.XMLHttpRequest.XML和JSON是构成Ajax技术体系技术基石. JavaScript ...
- IT兄弟连 JavaWeb教程 文件上传技术
在Web应用系统开发中,文件上传和下载功能是非常常用的功能. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参 ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Session技术
Servlet提供了HttpSession接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式. Servlet容器使用这个接口来创建一个HTTP客户端和HTTP服务器之 ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie技术原理
Cookie使用HTTPHeader传递数据.Cookie机制定义了两种报头,Set-Cookie报头和Cookie报头.Set-Cookie报头包含于Web服务器的响应头(ResponseHeade ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie技术简介
Cookie的英文原意是“点心”,它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,好像是服务器送给客户的“点心”.服务器可以根据Cookie来跟踪客户状态,这对于需要区别客户的场合(如 ...
- IT兄弟连 JavaWeb教程 MVC设计模式
MVC是Model-View-Controller的简称,即模型-视图-控制器.MVC是一种设计模式,它强制性地把应用程序的数据展示.数据处理和流程控制分开.MVC把应用程序分成3个核心模块:模型.视 ...
- IT兄弟连 JavaWeb教程 ServletContext对象
ServletContext是Servlet与Servlet容器之间直接通信的接口.Servlet容器在启动一个Web应用时,会为它创建一个ServletContext对象.每个Web应用都有唯一的S ...
- IT兄弟连 JavaWeb教程 jQuery对AJAX的支持经典面试题
1.简述对Ajax的理解 AJAX是Asynchronous JavaScript and Xml异步的JavaScript和Xml.它一种用来改善用户体验的技术其实质是使用XMLHttpReques ...
- IT兄弟连 JavaWeb教程 JSON和JSON字符串
JSON (JavaScript Object Notation)是JavaScript语言中的一种对象类型.JSON的好处是易于阅读和解析.当客户端和服务器端需要交互大量数据时,使用JSON格式传输 ...
随机推荐
- [Android] Gradle 安装
Gradle安装非常简单,只要从官网下载压缩包,解压,修改一下环境变量即可. 笔者写本篇随笔时,版本是1.12. Windows下安装 1 到官网(http://www.gradle.org/down ...
- myeclipse内存不足的处理
Myeclipse内存溢出解决方案 1.tomcat内存扩展 修改tomcat中bin目录下catalina.bat文件在echo Using CATALINA_BASE: "%CATAL ...
- Hadoop HA- zookeeper安装配置
安装集群 1.1 虚拟机: 3台安装好JDK的centos Linux虚拟机 1.2 安装包: 把下载好的zookeeper安装包,官网:http://mirror.bit.edu.cn/apache ...
- RQNOJ 514 字串距离:dp & 字符串
题目链接:https://www.rqnoj.cn/problem/514 题意: 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字 ...
- jQuery 获取有多个class名的元素
HTML内容: <div class="write-upload"> <p class="write-files old-files"> ...
- SocketSessionConfig参数设制
Mina 是一个韩国人写的基本java NIO的一个高性能的传输框架,我们的搜索就是基本它作为一个搜索服务开放接口了.对于系统的TIME_WAIT过多,造成服务器的负载过高,这个问题我也不用多说了,这 ...
- Java_泛型_01_T与?
二.参考文档 1.JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别
- Java的访问权限修饰符
default或者friendly表示默认的访问权限修饰符.
- vs中解决方案、项目、类及ATL的理解
解决方案,是对所有要完成工作的统称,一般叫Solution. 项目,也叫工程,是将解决方案分成若干个模块进行处理,一般叫做Project.添加项目就是添加工程.解决方案是所有项目的总和. 一个项目里面 ...
- Python定时任务-schedule vs. Celery vs. APScheduler
在Python开发过程中我们经常需要执行定时任务,而此类任务我们通常有如下选项: 自己造轮子 使用schedule库 使用Celery定时任务 使用APScheduler 自己造轮子实现,最大的优势就 ...