JavaWeb实现文件下载
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实现文件下载的更多相关文章
- javaWeb项目-文件下载的消息头和编码问题
一.问题: 做web项目经常提到的一个需求就是页面的文件下载,那么下载的时候在后台为什么要设置响应消息头?为什么这样设置? 二.解决: 1.例子 //设置响应的消息头response.setConte ...
- JavaWeb 之文件下载
1. 下载概述 下载就是向客户端响应字节数据! 将一个文件变成字节数组, 使用 response.getOutputStream() 来响应给浏览器!! 2. 下载要求 两个头一个流 Content- ...
- IT兄弟连 JavaWeb教程 文件下载技术
● 列出提供下载的文件资源 我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFile ...
- 文件名含中文的JavaWeb文件下载
在javaweb项目中实现文件下载,当文件名中包含中文文字时,需要进行如下的处理,才能在浏览器端正常显示中文文件名: response.setContentType("octets/stre ...
- [javaweb]javaweb中HttpServletResponse实现文件下载,验证码和请求重定向功能
HttpServletResponse web服务器接受到客户端的http请求之后,针对这个请求,分别创建一个代表请求的httpServletRequest和代表响应的HttpServletRespo ...
- JavaWeb文件下载,提示用户保存而不是让浏览器直接打开
1.通过HttpServletResponse对象实现文件下载 服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt.jpg等,会直接在浏览器中显示,如果需 ...
- javaweb文件下载
最近搞了一下struts文件上传下载了,一个是通过struts自带的类实现的下载方法,一个是通用的下载方法: struts实现: FileDownloadAction.java package com ...
- javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)
原博客地址:https://blog.csdn.net/weixin_37766296/article/details/80044000 将多个文件压缩并下载下来:(绿色为修改原博客的位置) 注意:需 ...
- javaweb简单的实现文件下载
public HttpServletResponse download(HttpServletRequest request, HttpServletResponse response) throws ...
随机推荐
- LeetCode 197. Rising Temperature (上升的温度)
题目标签: 题目给了我们一个 温度表格,让我们找到 所有温度比之前一天高的,返回id. 建立 Weather w1, Weather w2,找到当w1 的温度 大于 w2 的时候,而且 w1 的日期是 ...
- 基于Netty的RPC架构学习笔记(八):protocol buff学习使用
文章目录 简介 准备 protobuf配置文件 生成java代码 举个
- AtCoder ABC 128F Frog Jump
题目链接:https://atcoder.jp/contests/abc128/tasks/abc128_f 题目大意 给定长度为 N 的序列$s_0, s_1, \dots, s_{N-1}$,现在 ...
- 引入css文件时,css link和@import区别
这里link与@import介绍的是html引入css的语法单词.两者均是引入css到html的单词. 一.了解基本 1.link语法结构 <link href="CSSurl路径&q ...
- Java异常类及处理
异常概述:运行时发生的不正常情况 在java中用类的形式对不正常的情况进行了描述和封装对象. 描述不正常的类,称之为异常类. 异常就是java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述 ...
- Spring AOP源码分析(二):AOP的三种配置方式与内部解析实现
AOP配置 在应用代码中,可以通过在spring的XML配置文件applicationContext.xml或者基于注解方式来配置AOP.AOP配置的核心元素为:pointcut,advisor,as ...
- 大道浮屠诀---mysql5.7.28 for linux安装
环境: redhat6.5 MySQL Community Server 5.7.28 https://dev.mysql.com/downloads/mysql/5.7.html 安装RMP包的具体 ...
- Neo4j中实现自定义中文全文索引
数据库检索效率时,一般首要优化途径是从索引入手,然后根据需求再考虑更复杂的负载均衡.读写分离和分布式水平/垂直分库/表等手段:索引通过信息冗余来提高检索效率,其以空间换时间并会降低数据写入的效率:因此 ...
- javascript字符串方法学习汇总
1.charAt(index) charAt(index):返回字符串中指定位置的字符 var str = 'abcdefghi'; console.log(str.charAt()); // 输出 ...
- 转——调试寄存器 原理与使用:DR0-DR7
下面介绍的知识性信息来自intel IA-32手册(可以在intel的开发手册或者官方网站查到),提示和补充来自学习调试器实现时的总结. 希望能给你带去有用的信息. (DRx对应任意的一个调试寄存器. ...