参考许多文章,结合自己所需,备份
目的:在后台获取文件,以下是gsp页面内容
<g:form action="save" method="post" id="searchForm" enctype="multipart/form-data">
<div class="form-group">
<div class="label"><label>姓名</label></div>
<input type="user" id="user" name="user"/>
</div>
<div class="form-group">
<div class="label"><label>文件</label></div>
<input type="file" id="file" name="file"/>
<input type="submit" value="上传"/>
</div>
</g:form>
注:enctype=”multipart/form-data” 必须要写
有一种最直接了当的方式得到文件内容,上传,以下是NewsController代码
def save={
def file = request.getFile('file');
if (!file .empty){
def filename = file.originalFilename;//得到文件名
def rootDir = servletContext.getRealPath("/");//得到上传文件的保存目录
def uDir=new File(rootDir,"/load/");
//判断上传文件的保存目录是否存在
if (!uDir.exists() && !uDir.isDirectory()) {
println(uDir+"目录不存在,需要创建");
//创建目录
userDir.mkdirs();
}
int index = filename.lastIndexOf("."); //取得文件名中最后一个"."的索引
def newext = filename.substring(i); //获取文件扩展名此时可对文件拓展名做一些限制,比如照片格式,文档格式,媒体格式等
file.transferTo( new File( uDir, filename));
render action:~
}
}
但是这个时候页面也跟着刷新,在有些情况下,我们不希望页面被刷新,这种时候我们都是使用Ajax的方式进行请求的:
$.ajax({
url:"<%=request.getContextPath()%>/news/save",
type:'POST',
data:{user:$('#user').val()},
dataType:'json',
error:function () {
alert('提交错误');
},
cache:false,
success:function (msg) {
alert(成功);
}
});
但是上述方式,只能传递一般的参数,比如String类型的user,上传文件的文件流是无法传递的。
不过现在有一种方法,通过FormData对象可以传递任何类型的数据,轻松地使用Ajax方式进行文件上传了。
首先先学习如何使用FormData
FormData对象,是可以使用一系列的键值对来模拟一个完整的表单,通过jQuery使用FormData对象上传文件。参考文章
使用form表单初始化FormData对象方式上传文件
$.ajax({
url:"<%=request.getContextPath()%>/news/save",
type: 'POST',
cache: false,
data: new FormData($('#searchForm')[0]),
processData: false,
contentType: false,
error:function () {
alert('错误!');
},
success:function (msg) {
alert('成功');
}
});
注意:
- processData设置为false。因为data值是FormData对象,不需要对数据做处理。
- form标签添加enctype=”multipart/form-data”属性。
- cache设置为false,上传文件不需要缓存。
- contentType设置为false。因为是由form表单构造的FormData对象,且已经声明了属性enctype=”multipart/form-data”,所以这里设置为false。
使用form对象初始化FormData对象方式上传文件
html:
<div>
<div class="form-group">
<div class="label"><label>姓名</label></div>
<input type="user" id="user" name="user"/>
</div>
<div class="form-group">
<div class="label"><label>文件</label></div>
<input type="file" id="file" name="file"/>
<input type="submit" value="上传"/>
</div>
</div>
JavaScript:
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
formData.append('user',$('#user'));
$.ajax({
url:"",
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false,
error:function () {
alert('错误!');
},
success:function (msg) {
alert(msg.file+msg.user);
}
});
这里有几处不一样:
append()的第二个参数应是文件对象,即$(‘#file’)[0].files[0]
contentType也要设置为‘false
从代码$(‘#file’)[0].files[0]中可以看到一个input标签能够上传多个文件,只需在input添加multiple或multiple=”multiple”属性。
FormData传递数据,Grails读取数据
服务器端读取数据跟NewsController代码一样,因为FormData通过键值对的形式传递到服务器,因此只需
def fileName = params.file;
def userName = params.user;
就读到了数据内容