ajax文件上传怎么传其他参数,Ajax进行文件与其他参数的上传功能
光启元
转载
关注
0点赞·945人阅读
记得前一段时间,为了研究Ajax文件上传,找了很多资料,在网上看到的大部分是form表单的方式提交文件,对于Ajax方式提交文件并且也要提交表单中其他数据,发现提及的并不是很多,后来在同事的帮助下,使用ajaxfileupload最终完成了文件上传与其他提交的 *** 作,现在分享给大家,希望大家能有有所帮助。本文主要介绍了使用Ajax进行文件与其他参数的上传功能(java开发),非常不错,具有参考借鉴价值,需要的朋友参考下吧,希望能帮助到大家。
文件上传:
*** 作步骤:
1 导入jar包:
我们在使用文件上传时,需要使用到两个jar包,分别是commons-io与commons-fileupload,在这里我使用的两个版本分别是2.4与1.3.1版本的,需要使用JS文件与jar包最后会发给大家一个连接(如何失效请直接我给留言,我会及时更改,谢谢)。
2 修改配置文件:
当我们导入的jar包是不够的,我们需要使用到这些jar包,由于我当时使用的是SSM框架,所以我是在application-content.xml中配置一下CommonsMultipartResolver,具体配置方法如下:
104857600
4096
3 JSP文件:
大家对form表单提交问价的方式很熟悉,但是我们有很多情况下并不能直接使用form表单方式直接提交。这时候我们就需要使用Ajax方式提交,Ajax有很多的好处,比如当我们不需要刷新页面获希望进行局部刷新的时候,我们就可以使用Ajax。
JSP页面中引入的script代码<script>
function
ajaxFileUpload()
{
$("#loading").ajaxStart(function(){
$(this).show()
})//开始上传文件时显示一个图片
.ajaxComplete(function(){
$(this).hide()
})//文件上传完成将图片隐藏起来
$.ajaxFileUpload({
url:'AjaxImageUploadAction.action',//用于文件上传的服务器端请求地址
secureuri:false,//一般设置为false
fileElementId:'imgfile',//文件上传空间的id属性
<input
type="file"
id="imgfile"
name="file"
/>
dataType:
'json',//返回值类型
一般设置为json
success:
function
(data,
status)
//服务器成功响应处理函数
{
alert(data.message)//从服务器返回的json中取出message中的数据,其中message为在struts2中定义的成员变量
if(typeof(data.error)
!=
'undefined')
{
if(data.error
!=
'')
{
alert(data.error)
}else
{
alert(data.message)
}
}
},
error:
function
(data,
status,
e)//服务器响应失败处理函数
{
alert(e)
}
}
)
return
false
}
</script>
struts.xml配置文件中的配置方法:
<struts>
<package
name="struts2"
extends="json-default">
<action
name="AjaxImageUploadAction"
class="com.test.action.ImageUploadAction">
<result
type="json"
name="success">
<param
name="contentType">text/html</param>
</result>
<result
type="json"
name="error">
<param
name="contentType">text/html</param>
</result>
</action>
</package>
</struts>
上传处理的Action
ImageUploadAction.action
package
com.test.action
import
java.io.File
import
java.io.FileInputStream
import
java.io.FileOutputStream
import
java.util.Arrays
import
org.apache.struts2.ServletActionContext
import
com.opensymphony.xwork2.ActionSupport
@SuppressWarnings("serial")
public
class
ImageUploadAction
extends
ActionSupport
{
private
File
imgfile
private
String
imgfileFileName
private
String
imgfileFileContentType
private
String
message
=
"你已成功上传文件"
public
File
getImgfile()
{
return
imgfile
}
public
void
setImgfile(File
imgfile)
{
this.imgfile
=
imgfile
}
public
String
getImgfileFileName()
{
return
imgfileFileName
}
public
void
setImgfileFileName(String
imgfileFileName)
{
this.imgfileFileName
=
imgfileFileName
}
public
String
getImgfileFileContentType()
{
return
imgfileFileContentType
}
public
void
setImgfileFileContentType(String
imgfileFileContentType)
{
this.imgfileFileContentType
=
imgfileFileContentType
}
public
String
getMessage()
{
return
message
}
public
void
setMessage(String
message)
{
this.message
=
message
}
@SuppressWarnings("deprecation")
public
String
execute()
throws
Exception
{
String
path
=
ServletActionContext.getRequest().getRealPath("/upload/mri_img_upload")
String[]
imgTypes
=
new
String[]
{
"gif",
"jpg",
"jpeg",
"png","bmp"
}
try
{
File
f
=
this.getImgfile()
String
fileExt
=
this.getImgfileFileName().substring(this.getImgfileFileName().lastIndexOf(".")
+
1).toLowerCase()
/*
if(this.getImgfileFileName().endsWith(".exe")){
message="上传的文件格式不允许!!!"
return
ERROR
}*/
/**
*
检测上传文件的扩展名是否合法
*
*/
if
(!Arrays.<String>
asList(imgTypes).contains(fileExt))
{
message="只能上传
gif,jpg,jpeg,png,bmp等格式的文件!"
return
ERROR
}
FileInputStream
inputStream
=
new
FileInputStream(f)
FileOutputStream
outputStream
=
new
FileOutputStream(path
+
"/"+
this.getImgfileFileName())
byte[]
buf
=
new
byte[1024]
int
length
=
0
while
((length
=
inputStream.read(buf))
!=
-1)
{
outputStream.write(buf,
0,
length)
}
inputStream.close()
outputStream.flush()
}
catch
(Exception
e)
{
e.printStackTrace()
message
=
"文件上传失败了!!!!"
}
return
SUCCESS
}
}
转载,仅供参考。
javaweb上传文件上传文件的jsp中的部分
上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求
1.通过form表单向后端发送请求
<form id="postForm" action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data">
<div class="bbxx wrap">
<inputtype="text" id="side-profile-name" name="username" class="form-control">
<inputtype="file" id="example-file-input" name="avatar">
<button type="submit" class="btn btn-effect-ripple btn-primary">Save</button>
</div>
</form>
改进后的代码不需要form标签,直接由控件来实现。开发人员只需要关注业务逻辑即可。JS中已经帮我们封闭好了
this.post_file = function ()
{
$.each(this.ui.btn, function (i, n) { n.hide()})
this.ui.btn.stop.show()
this.State = this.Config.state.Posting//
this.app.postFile({ id: this.fileSvr.id, pathLoc: this.fileSvr.pathLoc, pathSvr:this.fileSvr.pathSvr,lenSvr: this.fileSvr.lenSvr, fields: this.fields })
}
通过监控工具可以看到控件提交的数据,非常的清晰,调试也非常的简单。
2.通过ajax向后端发送请求
$.ajax({
url : "${pageContext.request.contextPath}/UploadServlet",
type : "POST",
data : $( '#postForm').serialize(),
success : function(data) {
$( '#serverResponse').html(data)
},
error : function(data) {
$( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText)
}
})
ajax分为两部分,一部分是初始化,文件在上传前通过AJAX请求通知服务端进行初始化 *** 作
this.md5_complete = function (json)
{
this.fileSvr.md5 = json.md5
this.ui.msg.text("MD5计算完毕,开始连接服务器...")
this.event.md5Complete(this, json.md5)//biz event
var loc_path = encodeURIComponent(this.fileSvr.pathLoc)
var loc_len = this.fileSvr.lenLoc
var loc_size = this.fileSvr.sizeLoc
var param = jQuery.extend({}, this.fields, this.Config.bizData, { md5: json.md5, id: this.fileSvr.id, lenLoc: loc_len, sizeLoc: loc_size, pathLoc: loc_path, time: new Date().getTime() })
$.ajax({
type: "GET"
, dataType: 'jsonp'
, jsonp: "callback" //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
, url: this.Config["UrlCreate"]
, data: param
, success: function (sv)
{
_this.svr_create(sv)
}
, error: function (req, txt, err)
{
_this.Manager.RemoveQueuePost(_this.fileSvr.id)
alert("向服务器发送MD5信息错误!" + req.responseText)
_this.ui.msg.text("向服务器发送MD5信息错误")
_this.ui.btn.cancel.show()
_this.ui.btn.stop.hide()
}
, complete: function (req, sta) { req = null}
})
}
在文件上传完后向服务器发送通知
this.post_complete = function (json)
{
this.fileSvr.perSvr = "100%"
this.fileSvr.complete = true
$.each(this.ui.btn, function (i, n)
{
n.hide()
})
this.ui.process.css("width", "100%")
this.ui.percent.text("(100%)")
this.ui.msg.text("上传完成")
this.Manager.arrFilesComplete.push(this)
this.State = this.Config.state.Complete
//从上传列表中删除
this.Manager.RemoveQueuePost(this.fileSvr.id)
//从未上传列表中删除
this.Manager.RemoveQueueWait(this.fileSvr.id)
var param = { md5: this.fileSvr.md5, uid: this.uid, id: this.fileSvr.id, time: new Date().getTime() }
$.ajax({
type: "GET"
, dataType: 'jsonp'
, jsonp: "callback" //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
, url: _this.Config["UrlComplete"]
, data: param
, success: function (msg)
{
_this.event.fileComplete(_this)//触发事件
_this.post_next()
}
, error: function (req, txt, err) { alert("文件-向服务器发送Complete信息错误!" + req.responseText)}
, complete: function (req, sta) { req = null}
})
}
这里需要处理一个MD5秒传的逻辑,当服务器存在相同文件时,不需要用户再上传,而是直接通知用户秒传
this.post_complete_quick = function ()
{
this.fileSvr.perSvr = "100%"
this.fileSvr.complete = true
this.ui.btn.stop.hide()
this.ui.process.css("width", "100%")
this.ui.percent.text("(100%)")
this.ui.msg.text("服务器存在相同文件,快速上传成功。")
this.Manager.arrFilesComplete.push(this)
this.State = this.Config.state.Complete
//从上传列表中删除
this.Manager.RemoveQueuePost(this.fileSvr.id)
//从未上传列表中删除
this.Manager.RemoveQueueWait(this.fileSvr.id)
//添加到文件列表
this.post_next()
this.event.fileComplete(this)//触发事件
}
这里可以看到秒传的逻辑是非常 简单的,并不是特别的复杂。
var form = new FormData()
form.append("username","zxj")
form.append("avatar",file)
//var form = new FormData($("#postForm")[0])
$.ajax({
url:"${pageContext.request.contextPath}/UploadServlet",
type:"post",
data:form,
processData:false,
contentType:false,
success:function(data){
console.log(data)
}
})
java部分
文件初始化的逻辑,主要代码如下
FileInf fileSvr= new FileInf()
fileSvr.id = id
fileSvr.fdChild = false
fileSvr.uid = Integer.parseInt(uid)
fileSvr.nameLoc = PathTool.getName(pathLoc)
fileSvr.pathLoc = pathLoc
fileSvr.lenLoc = Long.parseLong(lenLoc)
fileSvr.sizeLoc = sizeLoc
fileSvr.deleted = false
fileSvr.md5 = md5
fileSvr.nameSvr = fileSvr.nameLoc
//所有单个文件均以uuid/file方式存储
PathBuilderUuid pb = new PathBuilderUuid()
fileSvr.pathSvr = pb.genFile(fileSvr.uid,fileSvr)
fileSvr.pathSvr = fileSvr.pathSvr.replace("\\","/")
DBConfig cfg = new DBConfig()
DBFile db = cfg.db()
FileInf fileExist = new FileInf()
boolean exist = db.exist_file(md5,fileExist)
//数据库已存在相同文件,且有上传进度,则直接使用此信息
if(exist &&fileExist.lenSvr >1)
{
fileSvr.nameSvr = fileExist.nameSvr
fileSvr.pathSvr= fileExist.pathSvr
fileSvr.perSvr = fileExist.perSvr
fileSvr.lenSvr = fileExist.lenSvr
fileSvr.complete = fileExist.complete
db.Add(fileSvr)
//触发事件
up6_biz_event.file_create_same(fileSvr)
}//此文件不存在
else
{
db.Add(fileSvr)
//触发事件
up6_biz_event.file_create(fileSvr)
FileBlockWriter fr = new FileBlockWriter()
fr.CreateFile(fileSvr.pathSvr,fileSvr.lenLoc)
}
接收文件块数据,在这个逻辑中我们接收文件块数据。控件对数据进行了优化,可以方便调试。如果用监控工具可以看到控件提交的数据。
boolean isMultipart = ServletFileUpload.isMultipartContent(request)
FileItemFactory factory = new DiskFileItemFactory()
ServletFileUpload upload = new ServletFileUpload(factory)
List files = null
try
{
files = upload.parseRequest(request)
}
catch (FileUploadException e)
{// 解析文件数据错误
out.println("read file data error:" + e.toString())
return
}
FileItem rangeFile = null
// 得到所有上传的文件
Iterator fileItr = files.iterator()
// 循环处理所有文件
while (fileItr.hasNext())
{
// 得到当前文件
rangeFile = (FileItem) fileItr.next()
if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))
{
pathSvr = rangeFile.getString()
pathSvr = PathTool.url_decode(pathSvr)
}
}
boolean verify = false
String msg = ""
String md5Svr = ""
long blockSizeSvr = rangeFile.getSize()
if(!StringUtils.isBlank(blockMd5))
{
md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream())
}
verify = Integer.parseInt(blockSize) == blockSizeSvr
if(!verify)
{
msg = "block size error sizeSvr:" + blockSizeSvr + "sizeLoc:" + blockSize
}
if(verify &&!StringUtils.isBlank(blockMd5))
{
verify = md5Svr.equals(blockMd5)
if(!verify) msg = "block md5 error"
}
if(verify)
{
//保存文件块数据
FileBlockWriter res = new FileBlockWriter()
//仅第一块创建
if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc))
res.write( Long.parseLong(blockOffset),pathSvr,rangeFile)
up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex))
JSONObject o = new JSONObject()
o.put("msg", "ok")
o.put("md5", md5Svr)
o.put("offset", blockOffset)//基于文件的块偏移位置
msg = o.toString()
}
rangeFile.delete()
out.write(msg)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)