由于项目需要,开发一个可以上传图片到服务器的web表单页面。
一、 需求
web表单页面,可以通过表单上传图片以及其他文字信息。
二、 图片上传的流程
之前没有做过这类页面,通过查询资料。发现比较常见的做法,是先将图片上传到服务器端的某个文件目录下,服务器向前台返回图片的存储路径;之后,前台将图片存储路径以及其他表单信息一起提交到服务器,所有的表单信息存储在数据库中。
三、 方法
由于项目需要,我这里介绍两种图片上传方法,第一种是使用ajax对一个图片直接上传;第二种是先在前台将图片切割为较小的文件,之后使用ajax分别上传图片到服务器,服务器实现对文件的拼接。(方法二适合较大文件的上传)下面我分别对两种方法做介绍。
方法一: 直接上传
1 html页面
<pre name="code" class="html"><!doctype html> <head></head> <body> <form id="uploadform" action="/picsubmit/form" method="post" enctype="multipart/form-data" onsubmit="return submit_check()" class="bootstrap-frm" ></pre><pre name="code" class="html"><input id = "sid" type = "text" name="name" /></pre><pre name="code" class="html"><pre name="code" class="html"><input id = "fileimage" type = "file" name="filename" /></pre><pre name="code" class="html"><input id = "addressid" type = "hidden" name="address" /></pre><pre name="code" class="html"><input id="ajaxsub" type="button" class="button" value="上传图片" onclick="fileupload()<span style="font-family: arial, helvetica, sans-serif;"> /> </span></pre><pre name="code" class="html"><input type="submit" class="button" value="提交表单" /> <input type="reset" class="button" value="重置表单" /> </pre></body></html><p></p> <pre></pre> <br> <pre></pre> 这一部分需要注意的是,form表单的enctype属性必须设置为“multipart/form-data”,在html5中,如果需要多张图片一起上传,可以在<input type="file"> 标签中,增加multiple属性,例如:<input type="file" id= “fileimage” multiple />。<br> <br> <br> <p></p> <p>2 js</p> <p>(1)js使用ajax提供的ajaxfileupload.js库。这个库使用起来还是比较方便的,和普通的ajax函数使用方法几乎相同。首先,需要ajaxfileupload.js库文件。这里需要注意,我之前在网上下载了一个ajaxfileupload.js文件不能用,浪费了很长时间,我直接把js库文件粘贴到这里,方便分享。</p> <p></p><pre name="code" class="javascript">// javascript document</pre><pre name="code" class="javascript">// ajax file uplaod jquery.extend({ createuploadiframe: function(id, uri) { //create frame var frameid = 'juploadframe' + id; if(window.activexobject) { var io = document.createelement('<iframe id="' + frameid + '" name="' + frameid + '" />'); if(typeof uri== 'boolean'){ io.src = 'javascript:false'; } else if(typeof uri== 'string'){ io.src = uri; } } else { var io = document.createelement('iframe'); io.id = frameid; io.name = frameid; } io.style.position = 'absolute'; io.style.top = '-1000px'; io.style.left = '-1000px'; document.body.appendchild(io); return io; }, createuploadform: function(id, fileelementid) { //create form var formid = 'juploadform' + id; var fileid = 'juploadfile' + id; var form = jquery('<form action="" method="post" name="' + formid + '" id="' + formid + '" enctype="multipart/form-data"></form>'); var oldelement = jquery('#' + fileelementid); var newelement = jquery(oldelement).clone(); jquery(oldelement).attr('id', fileid); jquery(oldelement).before(newelement); jquery(oldelement).appendto(form); //set attributes jquery(form).css('position', 'absolute'); jquery(form).css('top', '-1200px'); jquery(form).css('left', '-1200px'); jquery(form).appendto('body'); return form; }, ajaxfileupload: function(s) { // todo introduce global settings, allowing the client to modify them for all requests, not only timeout s = jquery.extend({}, jquery.ajaxsettings, s); var id = s.fileelementid; var form = jquery.createuploadform(id, s.fileelementid); var io = jquery.createuploadiframe(id, s.secureuri); var frameid = 'juploadframe' + id; var formid = 'juploadform' + id; if( s.global && ! jquery.active++ ) { // watch for a new set of requests jquery.event.trigger( ajaxstart ); } var requestdone = false; // create the request object var xml = {}; if( s.global ) { jquery.event.trigger(ajaxsend, [xml, s]); } var uploadcallback = function(istimeout) { // wait for a response to come back var io = document.getelementbyid(frameid); try { if(io.contentwindow) { xml.responsetext = io.contentwindow.document.body?io.contentwindow.document.body.innerhtml:null; xml.responsexml = io.contentwindow.document.xmldocument?io.contentwindow.document.xmldocument:io.contentwindow.document; }else if(io.contentdocument) { xml.responsetext = io.contentdocument.document.body?io.contentdocument.document.body.innerhtml:null; xml.responsexml = io.contentdocument.document.xmldocument?io.contentdocument.document.xmldocument:io.contentdocument.document; } }catch(e) { jquery.handleerror(s, xml, null, e); } if( xml || istimeout == timeout) { requestdone = true; var status; try { status = istimeout != timeout ? success : error; // make sure that the request was successful or notmodified if( status != error ) { // process the data (runs the xml through httpdata regardless of callback) var data = jquery.uploadhttpdata( xml, s.datatype ); if( s.success ) { // ifa local callback was specified, fire it and pass it the data s.success( data, status ); }; if( s.global ) { // fire the global callback jquery.event.trigger( ajaxsuccess, [xml, s] ); }; } else { jquery.handleerror(s, xml, status); } } catch(e) { status = error; jquery.handleerror(s, xml, status, e); }; if( s.global ) { // the request was completed jquery.event.trigger( ajaxcomplete, [xml, s] ); }; // handle the global ajax counter if(s.global && ! --jquery.active) { jquery.event.trigger(ajaxstop); }; if(s.complete) { s.complete(xml, status); } ; jquery(io).unbind(); settimeout(function() { try { jquery(io).remove(); jquery(form).remove(); } catch(e) { jquery.handleerror(s, xml, null, e); } }, 100); xml = null; }; } // timeout checker if( s.timeout > 0 ) { settimeout(function(){ if( !requestdone ) { // check to see ifthe request is still happening uploadcallback( timeout ); } }, s.timeout); } try { var form = jquery('#' + formid); jquery(form).attr('action', s.url); jquery(form).attr('method', 'post'); jquery(form).attr('target', frameid); if(form.encoding) { form.encoding = 'multipart/form-data'; } else { form.enctype = 'multipart/form-data'; } jquery(form).submit(); } catch(e) { jquery.handleerror(s, xml, null, e); } if(window.attachevent){ document.getelementbyid(frameid).attachevent('onload', uploadcallback); } else{ document.getelementbyid(frameid).addeventlistener('load', uploadcallback, false); } return {abort: function () {}}; }, uploadhttpdata: function( r, type ) { var data = !type; data = type == xml || data ? r.responsexml : r.responsetext; // ifthe type is script, eval it in global context if( type == script ) { jquery.globaleval( data ); } // get the javascript object, ifjson is used. if( type == json ) { eval( data = + data ); } // evaluate scripts within html if( type == html ) { jquery(<p>).html(data).evalscripts(); } return data; }, handleerror: function( s, xhr, status, e ) { // if a local callback was specified, fire it if ( s.error ) { s.error.call( s.context || s, xhr, status, e ); } // fire the global callback if ( s.global ) { (s.context ? jquery(s.context) : jquery.event).trigger( ajaxerror, [xhr, s, e] ); } } });</pre><p></p> <p><br> </p>
(2)之后调用ajaxfileupload.js库,编写图片上传脚本,这里命名为ajaxfileuplaod_implement.js
<p></p><pre name="code" class="javascript">function fileupload() { var inputobject = $(#fileimage).get(0); if(inputobject.value == ) { alert(清先选择需要上传的图片); return false; } $.ajaxfileupload({ url: '/picsubmit/pic', //服务器端请求地址 secureuri: false, //是否需要安全协议,一般设置为false type: 'post', fileelementid: 'fileimage', //文件上传域的id datatype: 'text', //返回值类型 一般设置为json enctype:'multipart/form-data',//注意一定要有该参数 success: function (data, status) //服务器成功响应处理函数 { data=decodeuri(data);//服务器端使用urlencode将中文字符编码,所以这里需要解码。这样做的目的是防止中文乱码 var address = json.parse(data); for(var i=0;i
<pre name="code" class="java"> @requestmapping(value=/pic) @responsebody public string submitpic(@requestparam(value = filename,required = false) multipartfile[] fileimage, httpservletrequest request){ if(fileimage == null){ return []; } return picsaveservice.savepic(fileimage); }</pre><br>
其中需要注意的是,如果前端html的input标签中使用了multiple属性,则表示标签支持上传多个图片,则controller的参数列表中,文件的类型使用multipartfile[],反之,如果没有使用multiple属性,表示上传的是一张图片,则controller使用multipartfile类型接收。
<p><br> </p><p>文件接收完成后,就可以对文件进行存储了,方法有很多,我这里举一个例子如下:</p> <p></p><pre name="code" class="java"> public string savepic(multipartfile[] fileimage){ //为图片改名 string oldname = ; string newname = ; string extension = ; //图片按照上传时间命名 simpledateformat sdf = new simpledateformat(yyyymmddhhmmsssss); //存储每张图片的信息 list<picconfirmdata> resultlist = new arraylist<picconfirmdata>(); //获取配置文件中图片的存储路径 string path = parameters.getinstance().getdatabaseprops().getproperty(pic_save_dir); //依次将图片存储到path路径下 for(int i=0;i
<p><br> </p> <link rel="stylesheet" href="http://static.jb51.net/public/res-min/markdown_views.css?v=1.0"> </pre>
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
怎样可以快速的获取ajax通信对象
h5开发时使用ajax上传base64格式图片
以上就是ajax+spring实现文件上传的详细内容。
