您的位置:首页 > 编程语言 > Java开发

java文件上传总结

2017-09-05 14:06 441 查看
最近公司项目用到文件上传,总结一下

第一种 传统表单上传比较简单,网上也有好多文章介绍,推荐一篇:表单方式文件上传和下载

再此只提醒两点:

一,form表单中要加入enctype="multipart/form-data" method="post"

POST上传文件

最早的HTTP POST是不支持文件上传的,在1995年,ietf出台了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以Content-Type的类型扩充了multipart/form-data用以支持向服务器发送二进制数据。因此发送post请求时候,表单<form>属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:

 ①application/x-www-form-urlencoded(默认值)

 ②multipart/form-data

二, 如果使用ssm框架时,不要有如下配置,不然会报错:fileupload插件调用upload.parseRequest(request)解析得到空值

<bean id="multipartResolver"

  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

  <!-- 设置上传文件大小的参数 ,当前为100M -->

  <property name="maxUploadSize" value="104857600" />

 </bean>

表单提交提醒很不方便,

第二种 写原生的Ajax,用XMLHttpRequest 和FormData对象

前台用的是jsp

<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>上海电信</title>
<jsp:include page="main.jsp"></jsp:include>
<script type="text/javascript">
function deviceTotal_check(){
var result=true;
var deviceTotal = $("#deviceTotal").val().trim();
var reg=/^[0-9]*$/;
if (deviceTotal == null || deviceTotal.length == 0){
result = false;
}
if(!reg.test(deviceTotal)){
result = false;
}
return result;
}
function enterFile_check(){
var result=true;
var enterFile = document.getElementById("enterFile").value;
if (enterFile == null || enterFile.length == 0){
result = false;
}
return result;
}
function deviceFile_check(){
var result=true;
var deviceFile = document.getElementById("deviceFile").value;
if (deviceFile == null || deviceFile.length == 0){
result = false;
}
return result;
}
//XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
function UpladFile() {
if(!enterFile_check()){
alert("企业附件不能为空!");
return false;
}
if(!deviceFile_check()){
alert("分机附件不能为空!");
return false;
}
if(!deviceTotal_check()){
alert("分机总数不合法!");
return false;
}
var fileObj1 = document.getElementById("enterFile").files[0]; // js 获取文件对象
var fileObj2 = document.getElementById("deviceFile").files[0]; // js 获取文件对象
var fileObj3 = $("#deviceTotal").val(); // js 获取文件对象
var FileController = "${pageContext.request.contextPath}/mvc/dataAcquisition/uploads";                    // 接收上传文件的后台地址
// FormData 对象
var form = new FormData();
//form.append("author", "hooyes");                        // 可以增加表单数据

form.append("enterFile", fileObj1);                           // 文件对象
form.append("deviceFile", fileObj2);                           // 文件对象
form.append("deviceTotal", fileObj3);                           // 文件对象

xhr.onreadystatechange = callBack;
xhr.open("post", FileController, true);
xhr.upload.addEventListener("progress", progressFunction, false);
xhr.send(form);
}

function progressFunction(evt) {
var progressBar = document.getElementById("progressBar");
var percentageDiv = document.getElementById("percentage");
if (evt.lengthComputable) {
//$("#alertModal").modal({show:true});
progressBar.max = evt.total;
progressBar.value = evt.loaded;
percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%";
}
if(evt.total==evt.loaded){
//$("#alertModal").modal('hide');

}
}
function callBack(){
if(xhr.readyState==4){
if(xhr.status==200){
var msg=$("#message").val();
clearInput();
alert("操作完成!"+msg)
//xhr.responseText;
}
}
}
function clearInput(){
$("#enterFile").val("");
$("#deviceFile").val("");
$("#deviceTotal").val("");
}
</script>

<style>
body {
font-family: "Times New Roman", "Microsoft YaHei", "微软雅黑", STXihei, "华文细黑", serif;
background-color: #F0F0F2;
}
</style>
</head>
<body>
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true" style="width:500px;margin-top:20px; margin-left: auto; margin-right: auto;">

<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne" style="background-color: #404f64;color: #ffffff;">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<b> 数据采集  </b>
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<input type="hidden" id="message" value="${msg }">
<table align="center" width="100%" class="form-inline">
<tr height="60px;">
<td align="right"><label >企业附件:</label></td>
<td>
<input class="form-control" style="width:230px;" type="file" id="enterFile" name="enterFile"/>
</td>
</tr>
<tr height="60px;">
<td align="right"><label >分机附件:</label></td>
<td>
<input class="form-control" style="width:230px;" type="file" id="deviceFile" name="deviceFile"/>
</td>
</tr>
<tr height="60px;">
<td align="right"><label >分机总数:</label></td>
<td>
<input name="deviceTotal" id="deviceTotal" class="form-control" style="width: 230px;height: 35px;"/>
</td>
</tr>
<tr>
<td style="padding-left:80px;" colspan="2">
<button type="button" onclick="UpladFile()" class="btn mybtn" style="width: 115px;height: 30px;background-color: #404f64;color: #ffffff">提交</button>
<button type="button" onclick="clearInput()" class="btn mybtn" style="width: 115px;height: 30px;background-color: #ff634d;color: #ffffff">清空</button>
</td>
</tr>
</table>
</div>
</div>
</div>

</div>
</body>
<div class="modal fade" id="alertModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">提示</h4>
</div>
<div class="modal-body">
<progress id="progressBar" value="0" max="100"></progress>
<span id="percentage"></span> </div>
</div>
</div>
</div>
</html>


后台是Java

@RequestMapping("/uploads")
public String uploads(HttpServletRequest request,HttpServletResponse response){

logger.debug("进入 DataAcquisitionController.uploads");
//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
StringBuffer path=new StringBuffer();
path.append("/WEB-INF/upload/");
path.append(sdf.format(date));
String savePath = request.getSession().getServletContext().getRealPath(path.toString());
//上传时生成的临时文件保存目录
String tempPath = request.getSession().getServletContext().getRealPath("/WEB-INF/temp");
File tmpFile = new File(tempPath);
File saveFile = new File(savePath);
if (!tmpFile.exists()) {
//创建临时目录
tmpFile.mkdir();
}
if(!saveFile.exists() && !saveFile.isDirectory()){
saveFile.mkdirs();
}
//消息提示
String message = "";
try{
//使用Apache文件上传组件处理文件上传步骤:
//1、创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
//设置上传时生成的临时文件的保存目录
factory.setRepository(tmpFile);
//2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//监听文件上传进度
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int arg2) {
logger.debug("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
}
});
//解决上传文件名的中文乱码
//            upload.setHeaderEncoding("UTF-8");
//3、判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(request)){
//按照传统方式获取数据
request.setAttribute("msg", "form表单为空");
return "dataAcquisition";
}

//设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
upload.setFileSizeMax(1024*1024);
//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
upload.setSizeMax(1024*1024*10);
//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> list = upload.parseRequest(request);
DataAcquisitionPo dataAcquisitionPo=new DataAcquisitionPo();
OperationDataPo operationDataPo=new OperationDataPo();
for(FileItem item : list){
String name = item.getFieldName();
//如果fileitem中封装的是普通输入项的数据
if(item.isFormField()){
String value = item.getString();
if("remark".equals(name)){
dataAcquisitionPo.setRemark(value);
}
if("deviceTotal".equals(name)){
dataAcquisitionPo.setDeviceTotal(value);
operationDataPo.setCount(Integer.valueOf(value));
}
}else{//如果fileitem中封装的是上传文件
//得到上传的文件名称,
String filename = item.getName();
filename=java.net.URLDecoder.decode(filename,"UTF-8");
logger.debug("filename:"+filename);
if(filename==null || filename.trim().equals("")){
continue;
}
//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
//处理获取到的上传文件的文件名的路径部分,只保留文件名部分
filename = filename.substring(filename.lastIndexOf("\\")+1);
//得到上传文件的扩展名
String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
//如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
logger.debug("上传的文件的扩展名是:"+fileExtName);
//获取item中的上传文件的输入流
InputStream in = item.getInputStream();
//得到文件保存的名称
SimpleDateFormat sd=new SimpleDateFormat("yyyyMMddhhmmssSSS");
Date dating=new Date();
String saveFilename = sd.format(dating)+"."+fileExtName;
//                    String saveFilename = sd.format(dating) + "_" + filename;
//创建一个文件输出流
FileOutputStream out = new FileOutputStream(savePath + "\\" + saveFilename);
if("enterFile".equals(name)){
dataAcquisitionPo.setAttachmentEnterprise(savePath + "\\" + saveFilename);
}
if("deviceFile".equals(name)){
dataAcquisitionPo.setAttachmentDevice(savePath + "\\" + saveFilename);;
}
//创建一个缓冲区
byte buffer[] = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = 0;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
while((len=in.read(buffer))>0){
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
out.write(buffer, 0, len);
}
//关闭输入流
in.close();
//关闭输出流
out.close();
//删除处理文件上传时生成的临时文件
//item.delete();
message = "文件上传成功!";
}
}
String userName=((UserPo) request.getSession().getAttribute("user")).getUserName();
dataAcquisitionPo.setOperator(userName);
//            dataAcquisitionService.insert(dataAcquisitionPo);

operationDataService.insert(operationDataPo);
}catch (FileUploadBase.FileSizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("msg", "单个文件超出最大值!!!");
return "dataAcquisition";
}catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("msg", "上传文件的总的大小超出限制的最大值!!!");
return "dataAcquisition";
}catch (Exception e) {
message= "文件上传失败!";
e.printStackTrace();
}
request.setAttribute("msg", message);
return "dataAcquisition";
}

第三种 用Ajax和FormData

function doUpload() {
var fileObj1 = document.getElementById("enterFile").files[0]; // js 获取文件对象
var fileObj2 = document.getElementById("deviceFile").files[0]; // js 获取文件对象
var fileObj3 = $("#deviceTotal").val(); // js 获取文件对象
var FileController = "${pageContext.request.contextPath}/mvc/dataAcquisition/uploads";                    // 接收上传文件的后台地址
// FormData 对象
var form = new FormData();
//form.append("author", "hooyes");                        // 可以增加表单数据

form.append("enterFile", fileObj1);                           // 文件对象
form.append("deviceFile", fileObj2);                           // 文件对象
form.append("deviceTotal", fileObj3);                           // 文件对象
$.ajax({
url: contextPath + "/mvc/dataAcquisition/doUploads",
type: "post",
data: form,
dataType : "json",
//async: false,
contentType: false, //不加后台会报异常FileUploadBase$InvalidContentTypeException
processData: false, //不加前台会报错Illegal invocation
success: function(data){
alert(data.msg);
},
error: function(data) {
alert("操作失败!!!");
}
});
}


第四种 用jquery.form.js里的ajaxForm(我没成功,有兴趣的可以用用)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: