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格式传输 ...
随机推荐
- 常用js方法函数
常用方法函数 1.深复制 // 1.深复制 function deepCopy(source) { var result = {}; for (var key in source) { result[ ...
- touchweb手机网站图片加载方法(canvas加载和延迟加载)
一.canvas图片加载 关于canvas加载,我的方法是,将文章中所有用到图片的地方,都用canvas代替,给canvas一个data-src,里面存放img的路径,通过canvas方法渲染图片.因 ...
- SQL语法之初级增删改查
SQL语法之初级增删改查 1.增 1.1插入单行 INSERT INTO [表名](列名) VALUES(列值) 语法如下: INSERT INTO bsp_Nproductclass(guid,pi ...
- Swift 烧脑体操(一) - Optional 的嵌套
前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...
- Machine Learning No.2: Linear Regression with Multiple Variables
1. notation: n = number of features x(i) = input (features) of ith training example = value of feat ...
- 数据结构ADT是什么
抽象数据类型的缩写 abstract data type .表示数据结构的抽象模型.数据结构是一个数据概念的定义,通过各种工具对数据结构的概念类型的描述称之为抽象数据类型,简单地说是指一个数学模型以及 ...
- Hadoop- Hadoop详解
首先所有知识以官网为准,所有的内容在官网上都有展示,所有的变动与改进,新增内容都以官网为准.hadoop.apache.org Hadoop是一个开源的可拓展的分布式并行处理计算平台,利用服务器集群根 ...
- Go丨语言package github.com/Go-SQL-Driver/MySQL: exec: "git": executable file not found in %PATH%解决方法
Go语言在添加第三方MySQL驱动的时候报错: go: missing Git command. See https://golang.org/s/gogetcmd package github.co ...
- linux 使用总结
shell 简单的实现守护进程 单纯的使用 &命令 + ctrl+D退出终端 原理: 关闭终端有两种方式,一种是点叉,这时候,你关闭的是gnome-terminal这个进程,而Bash是它的子 ...
- Hover show tips
像上面这种效果,hover1时显示2,且1和2有一定间距的东东,一般有两种实现办法: 1.用JS,原理:over1时让2显示,out1时开个定时器延迟500ms再消失,over2时清除定时器,out2 ...