1.在实现之前,需要为项目导入两个jar包:commons-fileupload 和 commons-io
如果项目是maven项目的话则在pom.xml中写入:
<!-- 文件上传依赖的jar包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2.在springmvc.xml中加入配置:
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxInMemorySize" value="10240" /> <!-- 最大内存大小 -->
<property name="maxUploadSize" value="-1" /> <!-- 最大文件大小,-1为不限制大小 -->
</bean>
在此之前我已经有写过一篇SpringMVC实现图片上传的博客,现在需要实现的是Ajax文件的上传,其实都大同小异。
Ajax实现文件上传时通过FormData实现的。
FormData概述:
FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。如果表单enctype属性设为multipart/form-data ,则会使用表单的submit()方法来发送数据,从而,发送数据具有同样形式。
FormData的主要用途有两个:
1、将form表单元素的name与value进行组合,实现表单数据的序列化,从而减少表单元素的拼接,提高工作效率。
2、异步上传文件。
这里FormData就介绍这么多,有兴趣的小伙伴可以自行去了解一下。
jsp页面代码:
<form action="" id="myForm" method="post" enctype="multipart/form-data">
<ul class="forminfo1">
<li>
<label>客户姓名:</label>
<select id="cid" name="cid" class="selectinput" style="line-height: 20px; width:273px;"></select>
</li>
<li>
<label>出租片区:</label>
<select id="aid" name="aid" class="selectinput" style="line-height: 20px;" style="line-height: 20px; width:273px"> <option value='0'>---请选择片区---</option></select>
</li>
<li>
<label>出租房屋:</label>
<select id="hid" name="hid" class="selectinput" style="line-height: 20px; width:273px">
<option value='0'>---请选择房屋---</option>
</select>
</li>
<li>
<label>出租押金:</label>
<input type="text" name="myj" id="myj" class="selectinput"> /元
</li>
<li>
<label>预收租金:</label>
<input type="text" name="myzj" id="myzj" class="selectinput"> /元
</li>
<li>
<label>下次收租时间:</label>
<input type="text" name="mbegintime" id="mbegintime" class="selectinput" onClick="WdatePicker({el:this,dateFmt:'yyyy-MM-dd'})" readonly="readonly">
</li>
<li>
<label>上传合同:</label>
<input type="file" name="file" id="file" class="selectinput">
</li>
<li>
<label> </label>
<input type="button" class="btn" value="添加" />
</li>
</ul>
</form>
js代码:
/** ****************************提交表单******************************* */
function commitItem() {
$(".btn").bind("click", function() {
var cid = $("#cid").val();
var hid = $("#hid").val();
var myj = $("#myj").val();
var myzj = $("#myzj").val();
var mbegintime = $("#mbegintime").val();
var file = $("#file").val(); //需要上传的文件
var myage = /^[0-9]*$/; // 正则表达式
var m = myage.test(myj);
var n = myage.test(myzj);
if (hid == 0) {
layer.tips('请选择房屋!', '#hid', {
tips : [ 2, 'red' ]
});
$("#hid").focus();
return false;
} else if (myj.length == 0) {
layer.tips('出租押金不能为空!', '#myj', {
tips : [ 2, 'red' ]
});
$("#myj").focus();
return false;
} else if (!m) {
layer.tips('出租押金只能为正数!', '#myj', {
tips : [ 2, 'red' ]
});
$("#myj").focus();
return false;
} else if (myzj.length == 0) {
layer.tips('预收租金不能为空!', '#myzj', {
tips : [ 2, 'red' ]
});
$("#myzj").focus();
return false;
} else if (!n) {
layer.tips('预收租金只能为正数!', '#myzj', {
tips : [ 2, 'red' ]
});
$("#myzj").focus();
return false;
} else if (mbegintime.length == 0) {
layer.tips('时间不能为空!', '#mbegintime', {
tips : [ 2, 'red' ]
});
$("#mbegintime").focus();
return false;
} else if (file.length == 0) { //判断文件不能为空
layer.tips('合同不能为空!', '#file', {
tips : [ 2, 'red' ]
});
$("#file").focus();
return false;
} else if(file.length != 0){
//判断文件类型,我这里根据业务需求判断的是Excel或者dox/docx文件
var fileName1 = file.substring(file.lastIndexOf(".") + 1).toLowerCase();
if(fileName1 != "xls" && fileName1 !="xlsx" && fileName1 !="doc" && fileName1 !="docx"){
layer.tips('请选择Execl文件或DOCX文档!', '#file', {
tips : [ 2, 'red' ]
});
$("#file").focus();
return false;
}else{
//创建一个formData对象实例来序列化表单
var formdata = new FormData($("#myForm")[0]);
formdata.append("file", $("#file")[0].files[0]); //调用append()方法来添加数据
$.ajax({ //Ajax发送请求
url : $webName + '/djrz/addDj.do',
type : "post",
data : formdata, // 要传到后台的数据,serialize序列化表单,因无法序列化file类型所以用formData对象
dataType : 'json', // 服务器返回的格式
contentType: false, // 不设置数据类型
processData: false, // 将数据转换成对象,不对数据做处理,故 processData: false
success : function(mydata) {
parent.layer.msg('添加成功!', {
icon : 6,
time : 3000
});
var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
parent.layer.close(index);
},
error : function(data) {
parent.layer.msg('添加成功!', {
icon : 1
});
var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
parent.layer.close(index);
}
});
}
}
});
}
- 若是平常的form表单提交Ajax发送请求的话,可以使用serialize()函数来序列化表单进行提交,但因serialize无法序列化file类型所以这里用formData对象实现表单数据的序列化;
- 在前台js中对将要提交上传的文件进行判断与拦截,若不符合规范则不允许用户提交,方便后台对提交的数据进行处理;
- new FormData() :创建一个formData对象实例时,可以直接将整个form表单加入到该对象中,然后data提交formdata就行,后台直接一个实体类类型参数来接收数据;
- 若还有其它参数需要提交,可以调用append()方法来继续添加数据,后台可根据相应的键值对取就行;或者也可以将form表单中实体类没有的属性,在实体类中加进去,这样可以直接提交整个form表单就行;
- 选择器后面的“[0]”不能省略!
- 注:在Ajax方法中需要指定两个变量:
contentType: false,
processData: false,
若不书写则请求将会发送不成功。
controller层:
/**
* 登记入住添加(合同文件上传)
*/
@RequestMapping("/djrz/addDj.do")
@ResponseBody
public String addDj(Mydj mydj,@RequestParam("file")MultipartFile file,HttpServletRequest request,HttpSession sess) throws IllegalStateException, IOException {
//上传文件的保存路径
String path = request.getServletContext().getRealPath("/myFiles/");
//获取上传的文件名
String filename = file.getOriginalFilename();
//自定义一个uuid(为了防止上传的文件重名)
String uuid =UUID.randomUUID().toString().replaceAll("-","");
filename = uuid+filename;
File filepath = new File(path,filename);
//判断路径是否存在,如果不存在就创建一个
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//将上传文件保存到一个目标文件当中
file.transferTo(new File(path + File.separator + filename));
//设置实体类中的mimg属性的值
mydj.setMimg(filename);
//设置实体类中的mdate属性的值
Date date = new Date();
mydj.setMdate(date);
//设置实体类中的eid属性的值
Myemp user = (Myemp) sess.getAttribute("user");
mydj.setEid(user.getEid());
//设置实体类中的mflag属性的值
mydj.setMflag(0);
//最后调用service层方法进行添加
mydjService.addDj(mydj);
return "success";
}
对于前台表单传过来的数据,可以直接用一个实体类进行接收,若实体类中没有表单中的属性,则可以直接根据表单中的name属性另取;或者根据append加入的键值对形式取。
只要数据的提交与接收没问题,那接下来就是后台的数据处理了。
通过获取或创建上传文件的保存路径,再对文件名进行一下处理,就可以将上传的文件保存到项目相应的文件夹内,而数据库就只需要存入文件所在的地址与文件名即可。