专栏首页老码农的一亩三分地IT兄弟连 JavaWeb教程 文件下载技术

IT兄弟连 JavaWeb教程 文件下载技术

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

本文链接:https://blog.csdn.net/ITXDL123/article/details/90746093

● 列出提供下载的文件资源

我们要将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 下载文件成功

从运行结果可以看到,我们的文件下载功能已经可以正常下载文件了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java并发编程:深入剖析ThreadLocal

    想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理。首先,本文先谈一下对ThreadLocal的理解...

    用户6182664
  • Spring Boot

    解释一下:Spring Boot 可以构建一切。Spring Boot 设计之初就是为了最少的配置,最快的速度来启动和运行 Spring 项目。Spring B...

    纯洁的微笑
  • Java 11正式发布,新特性解读

    北京时间 9 月 26 日,Oracle 官方宣布 Java 11 正式发布。这是 Java 大版本周期变化后的第一个长期支持版本,非常值得关注。你可以点击以下...

    纯洁的微笑
  • Java NIO 系列(转)

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作...

    用户6182664
  • Java 线程线程池初探

    所谓线程池,就是将多个线程放在一个池子里面(所谓池化技术),然后需要线程的时候不是创建一个线程,而是从线程池里面获取一个可用的线程,然后执行我们的任务。线程池的...

    纯洁的微笑
  • Hutool中那些常用的工具类和方法

    获取classPath下的文件,在Tomcat等容器下,classPath一般是WEB-INF/classes。

    macrozheng
  • 16 个超级实用的 Java 工具类

    在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类。

    孤独键客
  • 史上最难的一道Java面试题:分析篇

    http://www.jiangxinlingdu.com/thought/2017/10/16/thread-analysis.html

    纯洁的微笑
  • Java中的IO流知识总结

    1、是文件: FileInputStream, FileOutputStream, FileReader, FileWriter

    用户6182664
  • 给你一份详细的 Spring Boot 知识清单

    在过去两三年的Spring生态圈,最让人兴奋的莫过于Spring Boot框架。或许从命名上就能看出这个框架的设计初衷:快速的启动Spring应用。因而Spri...

    纯洁的微笑

扫码关注云+社区

领取腾讯云代金券