Java Web总结十八文件的上传和下载

一、实现Web开发中的文件上传功能,需完成如下两步操作:

  1、在web页面中添加上传输入项。

  2、在Servlet中读取上传文件的数据,并保存到本地硬盘中。

二、如何在web页面中添加上传输入项?

  1、<input type="file">标签用于在web页面中添加文件上传输入项,设置文件上传输入项时须注意:

    1)必须设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。

    2)必须把form的enctype属性值设为multipart/form-data。设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。

三、在web开发中实现文件上传功能,通常使用commons-fileupload组件实现。使用commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:

  1、commons-fileupload-1.3.1.jar

  2、commons-io-2.4.jar

四、上传文件的细节:

  1、中文乱码的问题

    1)普通字段的中文乱码问题:FileItem.getString("UTF-8"),FileItem表示上传表单中的表单项内容。

    2)上传字段的中文乱码问题:ServletUploadFile.setHeaderEncoding("UTF-8");

  2、临时文件的删除问题

    1)通过FileItem.delete()

    2)一定要在关闭IO流之后

  3、在同一个目录下上传相同文件名的问题

    1)将文件名拼接一个唯一标识符,即UUID

  4、单个目录下文件过多的问题

    1)采用位运算解决单个目录文件过多

    2)思路:

  5、为安全将上传的文件放入客户端无法直接访问的目录中的问题

    1)将上传的文件,放置到/WEB-INF/upload/目录下

  6、重构思想

    1)做到重用性

  7、自定义封装上传文件工具类的问题

  8、上传文件的大小问题

  9、上传多个文件的问题

  10、上传多个文件的界面问题

五、显示下载文件列表

  1)递归方式查询可供下载的文件,一定要有出口条件。

  2)使用Map<UUID文件名,真实文件名>收集可供下载的文件

  3)使用<c:url>和<c:param>对中文名进行URL编码

六、下载文件

  1、对传过来的中文编码进行URL解码

  2、通过UUID文件名,反向查到该文件所在的真实目录

七、文件上传下载与数据库结合

  1、在将上传文件保存的同时,写往数据库表,一个上传文件对应一条记录,确保uuidFileName双方一致。

八、上传和下载代码

1、文件目录图

2、UpDao.java

package com.gnnuit.web.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;

import com.gnnuit.web.domain.Up;
import com.gnnuit.web.util.JdbcUtil;

//向数据库添加up对象
public class UpDao {
public void addUp(Up up) throws SQLException {
QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());
String sql = "insert into up(username,realFileName,uuidFileName) values(?,?,?)";
qr.update(sql, new Object[] { up.getUsername(), up.getRealFileName(),
up.getUuidFileName() });
}
}

3、Up.java

package com.gnnuit.web.domain;

public class Up {
private int id;
private String username;
private String realFileName;
private String uuidFileName;

public Up() {
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getRealFileName() {
return realFileName;
}

public void setRealFileName(String realFileName) {
this.realFileName = realFileName;
}

public String getUuidFileName() {
return uuidFileName;
}

public void setUuidFileName(String uuidFileName) {
this.uuidFileName = uuidFileName;
}
}

4、User.java

package com.gnnuit.web.domain;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.fileupload.FileItem;

//封装上传文件的内容
public class User {
// 上传用户
private String username;
// 上传的文件
private List<FileItem> upfileList = new ArrayList<FileItem>();

public User() {
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public List<FileItem> getUpfileList() {
return upfileList;
}

public void setUpfileList(List<FileItem> upfileList) {
this.upfileList = upfileList;
}
}

5、NoUpfileException.java

package com.gnnuit.web.exception;

public class NoUpfileException extends Exception{

private static final long serialVersionUID = 1L;

}

6、UpfileSizeException.java

package com.gnnuit.web.exception;

public class UpfileSizeException extends Exception{

private static final long serialVersionUID = 1L;

}

7、UpfileTypeException.java

package com.gnnuit.web.exception;

public class UpfileTypeException extends Exception{

private static final long serialVersionUID = 1L;

}

8、DownLoadServlet.java

package com.gnnuit.web.servlet.download;

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;

import com.gnnuit.web.util.UploadUtil;

public class DownLoadServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取传过来的UUID文件名,参数带有中文,需要做处理
String uuidFileName = request.getParameter("fileName");
byte[] buf = uuidFileName.getBytes("ISO8859-1");
uuidFileName = new String(buf, "UTF-8");

// 根据UUID文件名获取真实文件名
int index = uuidFileName.lastIndexOf("_");
String realFileName = uuidFileName.substring(index + 1);

// 设置弹出下载框
String uploadPath = this.getServletContext().getRealPath(
UploadUtil.uploadPath);
String uuidFilePath = UploadUtil.makeUuidFilePath(uploadPath,
uuidFileName);
response.setHeader("Content-Disposition", "attachment; filename="
+ URLEncoder.encode(realFileName, "UTF-8"));

// 开始下载
FileInputStream fis = new FileInputStream(new File(uuidFilePath + "/"
+ uuidFileName));
OutputStream out = response.getOutputStream();
int len = 0;
buf = new byte[1024];
while ((len = fis.read(buf)) > 0) {
out.write(buf, 0, len);
}
fis.close();
out.close();
}

}

9、FileListServlet.java

package com.gnnuit.web.servlet.download;

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;

import com.gnnuit.web.util.UploadUtil;

public class FileListServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uploadPath = this.getServletContext().getRealPath(
UploadUtil.uploadPath);
Map<String, String> map = new HashMap<>();// key代表UUID文件名,value代表真实文件名
getFiles(uploadPath, map);
request.setAttribute("map", map);
request.getRequestDispatcher("/download.jsp")
.forward(request, response);
}

// 获取下载目录的所有文件
private void getFiles(String uploadPath, Map<String, String> map) {
File file = new File(uploadPath);
if (file.isFile()) {
// 是文件,不是目录
String uuidFileName = file.getName();
int index = uuidFileName.lastIndexOf("_");
String realFileName = uuidFileName.substring(index + 1);
map.put(uuidFileName, realFileName);
} else {
// 是目录
File[] files = file.listFiles();
for (File f : files) {
getFiles(f.getPath(), map);
}
}
}

}

10、UploadServlet.java

package com.gnnuit.web.servlet.upload;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gnnuit.web.dao.UpDao;
import com.gnnuit.web.domain.Up;
import com.gnnuit.web.domain.User;
import com.gnnuit.web.exception.NoUpfileException;
import com.gnnuit.web.exception.UpfileSizeException;
import com.gnnuit.web.exception.UpfileTypeException;
import com.gnnuit.web.util.UploadUtil;

public class UploadServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
User user = UploadUtil.doUpload(request);
String uploadPath = this.getServletContext().getRealPath(
UploadUtil.uploadPath);
List<Up> upList = new ArrayList<>();
// 写入硬盘
UploadUtil.doSave(user, uploadPath, upList);
//写入数据库
UpDao dao = new UpDao();
for (Up up : upList) {
dao.addUp(up);
}
request.setAttribute("message", "上传文件成功");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(
request, response);
} catch (UpfileSizeException e) {
e.printStackTrace();
request.setAttribute("message", "上传文件大小限制在200K以内");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(
request, response);
} catch (UpfileTypeException e) {
e.printStackTrace();
request.setAttribute("message", "只能上传JPG格式的文件");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(
request, response);
} catch (NoUpfileException e) {
e.printStackTrace();
request.setAttribute("message", "无上传文件");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(
request, response);
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message", "上传文件失败");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(
request, response);
}

}

}

11、up.sql

use mydb3;
drop table if exists up;
create table if not exists up(
id int primary key auto_increment,
username varchar(20) not null,
realFileName varchar(20) not null,
uuidFileName varchar(100) not null
);

12、JdbcUtil.java

package com.gnnuit.web.util;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public final class JdbcUtil {
private static ComboPooledDataSource cpds;
static {
cpds = new ComboPooledDataSource();
}

// 获取数据源
public static DataSource getDataSource() {
return cpds;
}

// 取得连接
public static Connection getMySqlConnection() throws SQLException {
return cpds.getConnection();
}

// 关闭连接
public static void close(Connection conn) throws SQLException {
if (conn != null) {
conn.close();
}
}
}

13、UploadUtil.java

package com.gnnuit.web.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.gnnuit.web.domain.Up;
import com.gnnuit.web.domain.User;
import com.gnnuit.web.exception.NoUpfileException;
import com.gnnuit.web.exception.UpfileSizeException;

public final class UploadUtil {
// 取得上传使用的临时和真实目录
public static final String tempPath = "/WEB-INF/temp";
public static final String uploadPath = "/WEB-INF/upload";

// 取得真实文件名
public static String getRealFileName(String realFileName) {
int index = realFileName.lastIndexOf("\\");
if (index >= 0) {
// IE6浏览器
realFileName = realFileName.substring(index + 1);
}
return realFileName;
}

// 取得uuid文件名
public static String makeUuidFilePath(String uploadPath, String uuidFileName) {
String uuidFilePath = null;
int code = uuidFileName.hashCode();// 8
int dir1 = code & 0xF;// 3
int dir2 = code >> 4 & 0xF;// A
File file = new File(uploadPath + "/" + dir1 + "/" + dir2);
// 如果该目录未存在
if (!file.exists()) {
// 一次性创建N层目录
file.mkdirs();
}
uuidFilePath = file.getPath();
return uuidFilePath;
}

// 取得upload/目录下的分散目录
public static String makeUuidFileName(String realFileName) {
return UUID.randomUUID().toString() + "_" + realFileName;
}

// 文件复制
public static void doSave(InputStream is, String uuidFileName,
String uuidFilePath) {
OutputStream os = null;
try {
os = new FileOutputStream(uuidFilePath + "/" + uuidFileName);
byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) > 0) {
os.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

// 将上传文件封装成JavaBean对象中
public static User doUpload(HttpServletRequest request) throws Exception {
User user = new User();
// 创建上传文件工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存中缓存区的大小,默认10K
factory.setSizeThreshold(100 * 1024);
// 设置上传文件临时存放的目录
String tempPath = request.getSession().getServletContext()
.getRealPath(UploadUtil.tempPath);
factory.setRepository(new File(tempPath));
// 创建上传文件对象[核心]
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置上传文件的中文编码方式
upload.setHeaderEncoding("UTF-8");
// 客户端上传文件是否使用MIME协议,
boolean flag = ServletFileUpload.isMultipartContent(request);
if (!flag) {
// 不是以MIME协议上传文件
throw new ServletException();
} else {
/*
* 是以MIME协议上传的文件,解析request中的所有上传内容每个内容封装成一个对象FileItem,
* FileItem代表普通字段和上传字段二类
*/
List<FileItem> fileItemList = upload.parseRequest(request);
for (FileItem fileItem : fileItemList) {
if (fileItem.isFormField()) {
String fieldValue = fileItem.getString("UTF-8");
user.setUsername(fieldValue);
} else {
// 必定是上传字段

// 如果无上传文件
if (fileItem.getSize() == 0) {
throw new NoUpfileException();
}

// 只能上传JPG文件
/*String realFileName = UploadUtil.getRealFileName(fileItem
.getName());
if (!realFileName.endsWith("jpg")) {
throw new UpfileTypeException();
}*/

// 只有上传<=200K的文件
if (fileItem.getSize() > 200 * 1024) {
throw new UpfileSizeException();
}

// 封装到JavaBean
user.getUpfileList().add(fileItem);

}
}// end of for loop
}
return user;
}

public static void doSave(User user, String uploadPath, List<Up> upList)
throws Exception {
// 取得该用户上传的所有文件集合
List<FileItem> fileItemList = user.getUpfileList();
// 迭代每个文件,并上传
for (FileItem fileItem : fileItemList) {
// 创建Up对象
Up up = new Up();
up.setUsername(user.getUsername());
// 取得输入流
InputStream is = fileItem.getInputStream();
// 取得真实文件名
String realFileName = fileItem.getName();
realFileName = UploadUtil.getRealFileName(realFileName);
// 取得UUID文件名
String uuidFileName = UploadUtil.makeUuidFileName(realFileName);
// 取得UUID文件路径
String uuidFilePath = UploadUtil.makeUuidFilePath(uploadPath,
uuidFileName);
// 保存
UploadUtil.doSave(is, uuidFileName, uuidFilePath);
// 收集Up信息
up.setUuidFileName(uuidFileName);
up.setRealFileName(realFileName);
upList.add(up);
// 删除临时文件
fileItem.delete();
}

}
}

14、c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/mydb3</property>
</default-config>
</c3p0-config>

15、message.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<body>
${message }
</body>
</html>

16、download.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<body>
<table align="center" border="1">
<tr>
<th>文件列表</th>
<th>操作</th>
</tr>
<c:forEach var="entry" items="${map }">
<tr>
<td>${entry.value }</td>
<td>
<c:url var="myURL" value="/DownLoadServlet">
<c:param name="fileName" value="${entry.key }"></c:param>
</c:url>
<a href="${myURL }" >下载</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>

17、upload.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript">
var time=0;
function addDiv(addButton) {
var outDiv=document.getElementById("outDiv");
var divElement= document.createElement("div");
var inputElement=document.createElement("input");
inputElement.type="file";
inputElement.name="filename";
var inputElement2=document.createElement("input");
inputElement2.type="button";
inputElement2.value="删除";
inputElement2.onclick=function(){
var parentNode= this.parentNode.parentNode;
parentNode.removeChild(this.parentNode);
time--;
if(time<5){
addButton.disabled=false;
}
};
divElement.appendChild(inputElement);
divElement.appendChild(inputElement2);
outDiv.appendChild(divElement);
time++;
if(time==5){
addButton.disabled=true;
}
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath }/UploadServlet" method="post" enctype="multipart/form-data">
<table border="1" align="center">
<tr>
<td>上传用户</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>上传文件</td>
<td>
<div id="outDiv">

</div>
<%--<input type="file" name="filename"/> --%>
<input type="button" value="添加" onclick="addDiv(this)"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="提交"/>
</td>
</tr>

<tr>
<td colspan="2" align="center">
<a href="${pageContext.request.contextPath }/FileListServlet">显示下载文件列表</a>
</td>
</tr>
</table>
</form>
</body>
</html>

Java Web总结十八文件的上传和下载

时间: 2024-10-17 14:21:07

Java Web总结十八文件的上传和下载的相关文章

java实现ftp文件的上传与下载

最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 2.然后是相关类的代码 /** * ftp链接常量 * */ public class Ftp { private String ipAddr;//ip地址 private Integer port;//端口号 private String userName;//用户名 private Strin

.net web开发——文件的上传和下载

以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  可以带参数 [HttpPost("upload")] public JsonResult uploadProject(IFormFile file, string userId) { if (file != null) { var fileDir = "D:\\aaa"

SpringMVC实现文件的上传和下载

前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:"用什么技术来实现一般网页上文件的上传和下载?是框架还是Java中的IO流".我回复他说:"使用SpringMVC框架可以做到这一点,因为SpringMVC为文件的上传提供了直接的支持,但需要依赖Apache提供Commons FileUpload组件jar包."鉴于这个问题,我上网也百度了一下,网上很多都是介绍的使用IO流来实现文件的上传和下载,也有说到框架的,但介绍的并不是很完整,今天小钱将和大家介绍使用Spr

在SpringMVC框架下实现文件的 上传和 下载

在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation=&

struts中文件的上传和下载

首先我们还是新建一个新的web project 取名为upload_test 然后在WebRoot中新建两个jsp页面 upload.jsp 和result.jsp 代码分别如下: upload.jsp Jsp代码   <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <% String path = request.getCont

Servlet方式实现文件的上传和下载

文件的上传和下载需要两个jar包  commons-fileupload-1.2.2.jar和commons-io-2.0.1.jar JSP页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Trans

springboot项目关于文件的上传与下载

springboot页面需要实现文件的上传与下载 贴出部分代码 html代码 文件的下载 <form target="name" id="download_dubbo_form" name="download_dubbo_form" method="post" action="/jfpointscore-test/download"> <button id="download_d

Spring MVC 实现文件的上传和下载

文件上传是项目开发中最常见的功能.为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data.只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器. 一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应.在2003年,Apache Software Foundation发布了开源的Commons File

iOS开发中文件的上传和下载功能的基本实现-备用

感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代码. 主控制器的关键代码: 复制代码代码如下: YYViewController.m#import "YYViewController.h" #define YYEnc