java实现文件上传
1.文件上传概述
就是把客户端(浏览器)的文件保存一份到服务器 说白了就是文件的拷贝
2.文件上传要求
2.1浏览器端要求(通用浏览器的要求)
- 表单提交方式 post
- 提供文件上传框(组件) input type="file"
- 表单的entype属性必须为 multipart/form-data(没有这个属性值的话, 文件的内容是提交不过去的)
2.2服务器端要求
要使用request.getInputStream()来获取数据.
注意:
若表单使用了 multipart/form-data ,使用原生request.getParameter()去获取参数的时候都为null
3.常见的文件上传框架
commons-fileupload : 偏底层
struts2(底层:commons-fileupload)
SpringMVC
serlvet3.0
...
4.这里介绍的是commons-fileupload的使用
commons-fileupload是apache出品的一款专门处理文件上传的工具类
使用步骤:
-
导入jar包
-
创建磁盘文件项工厂
DiskFileItemFactory factory=new DiskFileItemFactory(); -
创建核心上传对象
ServletFileUpload upload=new ServletFileUpload(factory); -
解析请求,获取所有的上传组件 List
Listlist=upload.parseRequest(request); -
遍历list 获取每一个上传项
FileItem的API:
getFiledName():获取标签里面name属性的值
isFormFiled():判断是否是普通上传组件;
true:普通上传组件
false:文件上传组件
- 普通上传组件, 不是File, 目的获得值
getString("utf-8"):获取(普通上传组件)用户输入的内容 - 文件上传组件 是File , 目的: 获得文件名, 获得文件的内容
getName():获取文件名称
getInputStream():获取文件的流(文件内容)
delete():删除文件上传时候产生的临时文件
Eg:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//创建磁盘文件项工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建核心上传对象
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//获得所有的上传组件
List<FileItem> list = fileUpload.parseRequest(request);
for (FileItem fileItem : list) {
//判断是否是文件上传
if(fileItem.isFormField()){
//普通上传组件
//获得标签的name属性值
String key = fileItem.getFieldName();
//获得普通上传组件的内容.括号中编码避免中文乱码
String value = fileItem.getString("utf-8");
}else{
//文件上传组件
//获得文件上传组件的输入流
InputStream is = fileItem.getInputStream();
//创建文件输出流
OutputStream os= new FileOutputStream("G:/1.txt");
//开始复制
IOUtils.copy(is, os);
//最后关闭流
os.close();
is.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
5上传注意问题
-
文件重名问题 后面的会把前面的覆盖掉
给文件取一个随机名称, uuid方式 或者 毫秒值+三个随机数 -
文件名称问题 目的是获得文件真实名字,不带盘符的
如果是低版本IE:文件名带盘符E:/data/Desktop/a.txt 其它的火狐,谷歌是文件本来的名字: a.txt
-
常见的目录分离
按用户划分 适合用户量不大的项目 < 1w
按时间划分 2018/03/21/17/07
按数量划分 eg:以2000个为单位
随机划分 写算法
附:解决文件上传问题的小工具.
import java.util.Random;
import java.util.UUID;
public class UploadUtils {
/**
* 获取文件真实名称
* 由于浏览器的不同获取的名称可能为:E:\data\Desktop\a.txt
* 最终获取的为 1.jpg
* @param name 上传上来的文件名称
* @return 真实名称
*/
public static String getRealName(String name){
//获取最后一个"/"
int index = name.lastIndexOf("\\");
return name.substring(index+1);
}
/**
* 获取随机名称
* @param realName 真实名称
* @return uuid 随机名称
*/
public static String getUUIDName(String realName){
//realname eg: a.jpg ---> UUID.jpg; a --- > UUID
//获取后缀名
int index = realName.lastIndexOf(".");
if(index==-1){
return UUID.randomUUID().toString().replace("-", "").toUpperCase();
}else{
return UUID.randomUUID().toString().replace("-", "").toUpperCase()+realName.substring(index);
}
}
/**
* 获取文件目录,可以获取256个随机目录
* @return 随机目录
*/
public static String getDir(){//
String s="0123456789ABCDEF";
Random r = new Random();
return "/"+s.charAt(r.nextInt(16))+"/"+s.charAt(r.nextInt(16));
}
}
前端页面示例:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/demo01" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="name"/> <br/>
文件:<input type="file" name="file"/> <br/>
<input type="submit" />
</form>
</body>
</html>