1. 编写文件上传Servlet

 public class FileUpload1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputStream in = null;
OutputStream out = null; // 获取上传文件目录
String savePath = this.getServletContext().getRealPath("/WEB-INF/upload"); try {
// 使用默认配置创建解析器工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 获取解析器
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(new ProgressListener() {
@Override
public void update(long l, long l1, int i) {
System.out.println("文件大小为:" + l1 + ",当前已处理:" + l);
}
});
// 解决上传文件名的中文乱码问题
upload.setHeaderEncoding("UTF-8");
// 上传表单是否为multipart/form-data类型
if (!upload.isMultipartContent(request)) {
return;
}
// 解析request的输入流
List<FileItem> fileItemList = upload.parseRequest(request);
// 迭代list集合
for (FileItem fileItem : fileItemList) {
if (fileItem.isFormField()) {
// 普通字段
String name = fileItem.getFieldName();
// 调用getString重载方法, 解决上传数据的中文乱码问题
String value = fileItem.getString("UTF-8");
System.out.println(name + "=" + value);
} else {
// 上传文件
// 获取上传文件名
String fileName = fileItem.getName();
// input:file没有指定上传文件时, 结束本次循环并继续下一次循环
if(fileName == null && fileName.trim().equals("")) {
continue;
}
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
// 使用UUID作为上传文件的名称
fileName = makeFileName(fileName);
// 获取输入流
in = fileItem.getInputStream(); // 上传文件名若不存在, 则先创建
File savePathDir = new File(savePath);
if (!savePathDir.exists()) {
savePathDir.mkdir();
} // 使用hash算法产生当前上传图片的随机目录
String currentFileSavePath = makePath(savePath, fileName); // 获取输出流
out = new FileOutputStream(currentFileSavePath + "\\" + fileName);
int len = 0;
byte[] buffer = new byte[1024];
while((len=in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} }
public String makeFileName(String fileName) {
return UUID.randomUUID().toString() + "_" + fileName;
}
public String makePath(String savePath, String fileName) {
// 根据文件名产生int型hashcode, 32位二进制
int hashcode = fileName.hashCode();
// 获取第4位 0-15
int dir1 = hashcode&0xf;
// 获取第5-8位 0-15
int dir2 = (hashcode&0xf0)>>4;
// 凭借随机目录
String dir = savePath + "\\" + dir1 + "\\" + dir2; // upload\2\4
// 若目录不存在时, 创建目录
File file = new File(dir);
if(!file.exists()) {
file.mkdirs();
}
return dir;
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

2. 编写获取所有下载文件名称Servlet

 /**
* Created by IntelliJ IDEA.
*
* @Auther: ShaoHsiung
* @Date: 2018/8/26 16:26
* @Title:
* @Description: 列出网站所有下载文件
*/
public class ListFileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取下载目录路径
String filePath = this.getServletContext().getRealPath("/WEB-INF/upload");
// 创建存储文件下载路径的Map集合
Map filePathMap = new HashMap();
// 将下载目录中所有文件名称存储到Map集合中
listFile(new File(filePath), filePathMap);
// 存储数据后跳转
request.setAttribute("map", filePathMap);
request.getRequestDispatcher("/listfile.jsp").forward(request, response);
} /**
* 将下载目录中所有文件名称存储到Map集合中
* @param file 下载目录
* @param filePathMap Map集合
*/
private void listFile(File file, Map filePathMap) {
if(!file.isFile()) {
// 文件为目录时
File[] files = file.listFiles();
for (File f : files) {
// 递归调用
listFile(f, filePathMap);
}
} else {
// 9349249849-88343-8344_阿_凡_达.avi 处理结果为: 阿_凡_达.avi
String realName = file.getName().substring(file.getName().indexOf("_")+1);
// 9349249849-88343-8344_阿_凡_达.avi -> 阿_凡_达.avi
filePathMap.put(file.getName(), realName);
}
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

3. 处理文件下载请求Servlet

 public class FileDownload extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取下载文件名称的key
String filename = request.getParameter("filename"); //23239283-92489-dfsd_阿凡达.avi
// 解决get请求的中文乱码问题
filename = new String(filename.getBytes("iso8859-1"),"UTF-8");
// 获取下载目录
String path = makePath(filename,this.getServletContext().getRealPath("/WEB-INF/upload"));
// 获取下载文件
File file = new File(path + "\\" + filename);
// 下载文件不存在时
if(!file.exists()){
request.setAttribute("message", "您要下载的资源已被删除!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
// 获取下载文件名称 阿凡达.avi
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(); } /**
* 根据文件名称产生随机目录并将下载路径与随机目录拼接
* @param filename 文件名称
* @param savePath 下载路径
* @return 下载路径与随机目录拼接结果
*/
private String makePath(String filename,String savePath){ int hashcode = filename.hashCode();
int dir1 = hashcode&0xf; //0--15
int dir2 = (hashcode&0xf0)>>4; //0-15 String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5
File file = new File(dir);
if(!file.exists()){
file.mkdirs();
}
return dir;
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

4. 配置web.xml

 <!-- 文件上传 -->
<servlet>
<servlet-name>FileUpload1</servlet-name>
<servlet-class>fileupload.FileUpload1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUpload1</servlet-name>
<url-pattern>/servlet/FileUpload1</url-pattern>
</servlet-mapping> <!--文件下载-->
<servlet>
<servlet-name>ListFileServlet</servlet-name>
<servlet-class>fileupload.ListFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListFileServlet</servlet-name>
<url-pattern>/servlet/ListFileServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>FileDownload</servlet-name>
<servlet-class>fileupload.FileDownload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileDownload</servlet-name>
<url-pattern>/servlet/FileDownload</url-pattern>
</servlet-mapping>

5. 编写获取文件名称JSP

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'listfile.jsp' starting page</title>
</head> <body> <c:forEach var="me" items="${map}">
<c:url value="/servlet/FileDownload" var="downurl">
<c:param name="filename" value="${me.key}"></c:param>
</c:url>
${me.value } <a href="${downurl}">下载</a> <br/>
</c:forEach> </body>
</html>

注意:

URL地址栏 -> 非ASCII码字符 -> URL编码
使用c:url传递中文数据

6. 编写文件上传JSP

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>演示文件上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/FileUpload1" method="post" enctype="multipart/form-data">
用户名: <input type="text" name="username"/><br/>
文件1: <input type="file" name="file1"/><br/>
文件2: <input type="file" name="file1"/><br/>
<input type="submit"/>
</form>
</body>
</html>

7. 效果演示

在浏览器中访问http://localhost:8080/servlet/ListFileServlet

JavaWeb实现文件下载的更多相关文章

  1. javaWeb项目-文件下载的消息头和编码问题

    一.问题: 做web项目经常提到的一个需求就是页面的文件下载,那么下载的时候在后台为什么要设置响应消息头?为什么这样设置? 二.解决: 1.例子 //设置响应的消息头response.setConte ...

  2. JavaWeb 之文件下载

    1. 下载概述 下载就是向客户端响应字节数据! 将一个文件变成字节数组, 使用 response.getOutputStream() 来响应给浏览器!! 2. 下载要求 两个头一个流 Content- ...

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

    ●  列出提供下载的文件资源 我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFile ...

  4. 文件名含中文的JavaWeb文件下载

    在javaweb项目中实现文件下载,当文件名中包含中文文字时,需要进行如下的处理,才能在浏览器端正常显示中文文件名: response.setContentType("octets/stre ...

  5. [javaweb]javaweb中HttpServletResponse实现文件下载,验证码和请求重定向功能

    HttpServletResponse web服务器接受到客户端的http请求之后,针对这个请求,分别创建一个代表请求的httpServletRequest和代表响应的HttpServletRespo ...

  6. JavaWeb文件下载,提示用户保存而不是让浏览器直接打开

    1.通过HttpServletResponse对象实现文件下载 服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt.jpg等,会直接在浏览器中显示,如果需 ...

  7. javaweb文件下载

    最近搞了一下struts文件上传下载了,一个是通过struts自带的类实现的下载方法,一个是通用的下载方法: struts实现: FileDownloadAction.java package com ...

  8. javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)

    原博客地址:https://blog.csdn.net/weixin_37766296/article/details/80044000 将多个文件压缩并下载下来:(绿色为修改原博客的位置) 注意:需 ...

  9. javaweb简单的实现文件下载

    public HttpServletResponse download(HttpServletRequest request, HttpServletResponse response) throws ...

随机推荐

  1. 微信-小程序-开发文档-服务端-模板消息:templateMessage.getTemplateLibraryById

    ylbtech-微信-小程序-开发文档-服务端-模板消息:templateMessage.getTemplateLibraryById 1.返回顶部 1. templateMessage.getTem ...

  2. java: java中的 getInstance() 的理解

    原文地址:https://blog.csdn.net/qq_26293573/article/details/78184844 在单例模式下使用 . 单例模式:所谓单例模式就是一个类有且只有一个实例, ...

  3. 6. 第一个jmeter脚本开发-测试百度首页

    需求:可以承受5个用户同时访问百度解题思路:我们可以从这短短的一句话中提取3个点:同时.5个并发.百度服务器解题方法:方法一:录制请求录制方法会在下一篇进行讲解,本篇不做过多介绍. 方法二:自定义添加 ...

  4. 剑指offer——05重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  5. sql实现查询某个字段在哪个表里 及结构是什么

    ) --数据库名 ) set @dbname2='aab' select @str = ' SELECT 表名=d.name,字段名=a.name,序号=a.column_id, 标识=is_iden ...

  6. C++类成员变量多用指针不用对象

    如A类的成员变量含有B类的对象,那么每个A类对象产生或拷贝都要产生一次B类对象的构造或者拷贝,对象占的空间比较大,对象拷贝比较消耗内存. 如果换成B类的指针,A类对象拷贝,也只会产生4个字节或者8个字 ...

  7. FCC——相关练习

    算法题目1:Seek and Destroy(摧毁数组) 金克斯的迫击炮! 实现一个摧毁(destroyer)函数,第一个参数是待摧毁的数组,其余的参数是待摧毁的值. 帮助资源: Arguments ...

  8. INSTALL_FAILED_TEST_ONLY oppor11p 安装时出现的问题

      刚开始出现这个问题 我很懵逼, 因为我之前一直运行都好好的  !!我在网上查了好多资料 试了好几种办法 我先说下我成功的办法       方法1: Android Studio 3.0会在debu ...

  9. yii2中使用定义在 params.php文件中的配置

    yii2 使用 配置文件中在 params 的配置, 可以用 Yii::$app->params['key1']形式访问 参考 yii can't access Yii::$app->pa ...

  10. java8--Stream的flatmap与map异同的理解

    大纲: 异同点 示例 一.异同点 他们的相同点是接收的入参都是一个function. 不同点这个入参function的返回不同.map返回一个对象,flatmap返回一个stream. 这就使得map ...