利用ajaxFileUpload进行文件的上传,这里绝对有你想要的

版权声明:本篇文章由IT_CREATE整理 https://blog.csdn.net/IT_CREATE/article/details/85072591

首先先说明一下,我写的代码是jquery和js相结合的,可能有点low。

本次上传我用到了ajaxFileUpload进行文件的上传,我会分为两个部分来说,分别是:(这两个部分其实是互不干扰的,如果你不想用我写的这个控件的效果,那么只需要看后面第二点即可)

1)file控件的美化

传统的file控件如下,这种是非常原始的,很low,用bootstrap的file组件也可以,很美观,那么上传文件的方式就要遵循这个组件的要求,这里,我没有用它,我是自己从新写了一个,会实现不同的效果,虽然也不咋地。

<input type="file" id="images_file" name="images_file">

原始控件图:

2)ajaxFileUpload上传文件的实际操作

这里用这个来做也是为了方便,但是从网上下载了这个js之后有一些问题,后面我做了一些修改,我会说,你要用这个组件直接新建个js,取名为ajaxFileUpload,然后把我贴出来的代码复制进去就行了。

下面进入正题

因为我用的是jsp结合servlet做的,所以在用这两个东西的朋友可以看下,虽然现在没人用jsp了,只是学习用还是可以的。

1)jsp页面的代码

----------file控件部分

效果:

从这里可以看到,按钮换到了右边,是我想要的效果

代码如下:当一个页面中有多个地方要进行文件上传的,那么就需要去修改下面代码中两个<input>的id,同时对两个方法中的参数进行相应的修改

html/jsp:

<label style="margin-left: -5em;margin-right: 2em;color: white;">文件上传</label>
<!-- 下面这个输入框用于在页面显示选取的文件名,传入后台图片的路径地址就传images_name的值到后台-->
<input type="text" class="inputContent" id="file_name" readonly/>
<!-- 下面这个是实际选择文件的file控件,只是隐藏了,在这个标签中调用了一个我自己写的方法,需要传入上面用于显示文件名字的输入框的id,和自身的id-->
<input type="file" id="file_obj" name="file_obj" onchange="fileChoice('file_name','file_obj')" style="display: none">
<!-- 用于可以手动清空显示文件名输入框的内容,也就是上面input--text的内容 -->
<button class="clearFileName" id="clearFileName">×</button>
<!--下面这个按钮是用来触发上面的file控件的,传入上面file控件的id-->
<button type="button" class="btn btn-default btn-sm" onclick="fileUp('file_obj')" >浏览</button>
<br><br style="line-height: 1em">

css:

.inputContent{
    background-color: #e3e3e3;
    border: none;
    display: inline-block;
    margin-left: 1em;
    height: 2em;
    width: 12em;
}

.clearFileName{
	height: 2em;
	background-color: #e3e3e3;
	vertical-align: middle;
	border: 0px
}

上面的点击按钮的样式我用到了bootstrap的样式,你也可以自己定义css

这里我需要说下,我在js中写了两个方法用于之后的效果显示,就是上面的fileChoice()和fileUp方法,在上面的代码中,你可以看到有两个<input>,一个type=text,一个type=file;type=text的是用于显示选中之后文件的名字的,type=file的是做了隐藏的,主要是当我点击了按钮之后会触发这个file,实现选择的效果。如下:

点击按钮之后就出现了这个弹出框,就是触发了这个file,用来选择文件的。

文件选择之后,会弹出模态框,点击了模态框的上传按钮之后就是这个效果:

用作显示的input框就是上面的input-----text

下面这个是个模态框,当我们选择了文件之后,就会弹出这个模态框,这个模态框直接复制就可以,是不需要做任何处理的,我已经写好了,上面那串代码可能还要改一下id,这个不需要动。

模态框代码如下:

<!--文件上传显示模态框,该模态框一个页面只需要一个就可以了,该区域不用你们管-->
	<div class="modal fade" id="fileUpModal" tabindex="-1" role="dialog"
		aria-labelledby="imageUp" aria-hidden="true">
		<div class="modal-dialog">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal"
						aria-hidden="true">&times;</button>
					<h4 class="modal-title" id="imageUp">文件上传</h4>
				</div>
				<div class="modal-body" id="caseDescDiv">
					<!--用于保存当前文件使用的为哪个file控件的id -->
					<input type="text" id="file_obj_save" style="display: none">
					<!--用于保存显示文件名的input输入框的id-->
					<input type="text" id="file_name_save" style="display: none">
					
					<p style="text-align: center">

                        <!-- 如果上传的是图片,用这个显示上传的图片-->
						<img class="img" src=""/><br>
                        
                        <!-- 如果上传的不是图片,用下面这个现实一个随机的图标--> 
						<img class="img2" src=""/>

                        <!-- 显示上传的文件的名称--> 
						<span id="fileNameShow"></span><br>
                        
                        <!--显示上传状态-->
						<span id="fileUpWarn"></span>
					</p>
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-default" data-dismiss="modal"
						id="close_model">关闭</button>
					<button type="button" id="submitBtn" class="btn btn-primary">上传</button>
				</div>
			</div>
			<!-- /.modal-content -->
		</div>
		<!-- /.modal -->
	</div>

css:

.img{
    width: 30em;
}

.img2{
	height: 3em;
}

那么效果图如下:

选择的是图片的效果:

选择的不是图片的其他文件效果:

当我们点击之前的“浏览”按钮之后,并且在选择了相应的文件之后,就会弹出来这么一个模态框,上面有两个按钮,一个关闭,一个上传按钮,到这里,也就是关于file控件的美化部分,因为上传处理是单独的处理,只是对这个上传按钮添加一个点击事件罢了。

效果的js代码如下:

function fileUp(str) {
	// 触发file控件的点击事件
	document.getElementById(str).click();
}

function fileChoice(fileName, fileWidget) {
	// 获得input--file控件对象
	var objFileWidget = document.getElementById(fileWidget);
	// 获取file上传的文件
	var file = objFileWidget.files[0];
	// 获取用于显示文件名的input--text输入框
	var objFileName = document.getElementById(fileName);

	// 给模态框中的隐藏id为file_obj_save的input--text输入框赋值,保存正在使用的input--file控件的id
	var file_obj_save = document.getElementById("file_obj_save");
	file_obj_save.value = fileWidget;
	// 给模态框中的隐藏id为file_name_save的input--text输入框赋值,保存显示文件名输入框的id
	var file_name_save = document.getElementById("file_name_save");
	file_name_save.value = fileName;
	
    // 给显示文件名的input赋值
	objFileName.value = file.name;
	
    //将模态框中的所有用于显示的标签内容清空
	$(".img").attr("src", "");
	$(".img2").attr("src", "");
	document.getElementById("fileNameShow").innerHTML = "";
	document.getElementById("fileUpWarn").innerHTML = "";
	
	// 显示文件模态框
	$('#fileUpModal').modal('show');

	//判断文件是否是图片,如果是图片执行if里面的操作,显示图片和图片名称
	if ((file.type).indexOf("image/") != -1) {
		// 将图片写入到模态框里显示图片
		if (window.FileReader) {
			var reader = new FileReader();
			reader.readAsDataURL(file);
			// 监听文件读取结束后事件    
			reader.onloadend = function(e) {
				//显示图片
				$(".img").attr("src", e.target.result); // e.target.result就是最后的路径地址
				//显示文件名
				document.getElementById("fileNameShow").innerHTML = file.name;
			};
		}
	} else {
		//不是图片的话随机显示图标
		$(".img2").attr("src", getImg());
		//显示文件的名字
		document.getElementById("fileNameShow").innerHTML = file.name;
	}
}

//随机获得图标地址
function getImg() {
	var randomNum = Math.round(Math.random() * 10);
	console.log(randomNum);
	var img = "";
	if(randomNum == 0){
		img = "../static/img/file1.png";
	}else if(randomNum == 1){
		img = "../static/img/file2.png";
	}else if(randomNum == 2){
		img = "../static/img/file3.png";
	}else if(randomNum == 3){
		img = "../static/img/file4.png";
	}else if(randomNum == 4){
		img = "../static/img/file5.png";
	}else if(randomNum == 5){
		img = "../static/img/file6.png";
	}else if(randomNum == 6){
		img = "../static/img/file7.png";
	}else if(randomNum == 7){
		img = "../static/img/file8.png";
	}else if(randomNum == 8){
		img = "../static/img/file9.png";
	}else if(randomNum == 9){
		img = "../static/img/file10.png";
	}else if(randomNum == 10){
		img = "../static/img/file11.png";
	}
	return img;	
}

上面这段js就是我之前说过的两个方法,记住这两个方法千万不要写下面这串代码里面,因为这个表示的是页面一来就加载的内容,是动态的内容,而上面的方法是写死的,是静态的,在jsp上是直接调用的这两个方法,所以是静态的,写在这个这串代码的外部就行。这里只是说下,如果你在代码中用到了下面的代码情况下。

我建议:将我写出来的js、css单独写在相应的一个js、css文件中,这样能够实现复用,只需在jsp中引入即可

$(function() {

});

2)ajaxFileUpload进行文件上传

下面就是正经的文件上传部分了,首先说一下,刚才看到了,模态框上有两个按钮,一个关闭,一个上传,那么我就对这两个按钮进行了添加点击事件处理。如果你是直接用的下面这个

<input type="file" id="file" name="file"/>
<button>上传</button>

那么你只需要对这个button添加一个点击事件即可,那么代码都差不多,只需在点击事件方法中调用下面ajaxFileUpload(fileid, url)这个方法即可,这个方法也是我写好的,只需要传入上面file的id和需要传到后台服务器的路径url即可。

下面是代码:包括两个按钮的点击事件,和一个ajaxFileUpload(fileid, url)方法

//以下所有代码都是为文件上传所写的js
$(function() {
	//点击jsp上那个叉叉按钮清除文件名显示框的内容
	$('#clearFileName').bind("click", function() {
		var file_name_save = document.getElementById("file_name_save");
		var file_name_save_value = file_name_save.value;
		var objFileName = document.getElementById(file_name_save_value);

		// 清空用于显示文件名的输入框的内容
		objFileName.value = "";
	});

   //模态框关闭按钮点击操作
	$('#close_model').bind("click", function() {
		// 获得模态框中保存input---text用于显示文件名的输入框的input输入框的对象,自己去看模态框部分,你就看懂了
		var file_name_save = document.getElementById("file_name_save");
		var file_name_save_value = file_name_save.value;
		var objFileName = document.getElementById(file_name_save_value);

		// 清空用于显示文件名的输入框的内容
		objFileName.value = "";
		// 隐藏文件模态框
		$('#fileUpModal').modal('hide');

	});
	
    //点击上传按钮后的点击事件
	$('#submitBtn').bind("click", function() {
		document.getElementById("fileUpWarn").innerHTML = "正在上传中,请稍后。。。。";
		// 获得模态框中保存input---file控件id的input输入框的对象
		var file_obj_save = document.getElementById("file_obj_save");
		// 获得这个对象里面保存的具体的file控件id
		var file_obj_save_value = file_obj_save.value;

		var url = getPath() + "/upfile";// 获得后台servlet的路径

		// 传入input----file的id,和上传路径
		ajaxFileUpload(file_obj_save_value, url);// 调用ajax文件上传的方法,该方法是自己写的,自己去看模态框部分,你就看懂了


	});

	// 用于上传的方法,自己写的
	function ajaxFileUpload(fileid, url) {

		
		// 通过id获得input----file这个控件的对象
		var fileObj = document.getElementById(fileid);

		// 调用ajaxFileUpload的方法了
		$
				.ajaxFileUpload({
					url : url, // 用于文件上传的服务器端请求地址
					type : 'post',// 提交方式
					contentType : 'multipart/form-data',// 提交内容以什么类型提交
					data : {
						file : fileObj
					},// 提交的内容
					secureuri : false, // 是否需要安全协议,一般设置为false
					fileElementId : fileid, // 文件上传域的ID
					dataType : 'json', // 返回值类型 一般设置为json
					success : function(data, status) // 服务器成功响应处理函数
					{
                        
						document.getElementById("fileUpWarn").innerHTML = data.information; //上传成功后在模态框中显示返回消息
                        
						setTimeout(function () {
							$('#fileUpModal').modal('hide');
							 }, 1000);//上传成功后1秒后隐藏模态框
					},
					error : function(data, status, e)// 服务器响应失败处理函数
					{
						alert(e);
					}
				});
		
	}

});

在上面中你可看到我去获得后台servlet路径时有一个getPath()方法,代码如下,主要是获得项目的名称

//获得项目名称
function getPath() {
	var pathName = window.document.location.pathname;
	var projectName = pathName
			.substring(0, pathName.substr(1).indexOf('/') + 1);
	return projectName;
}

那么在使用ajaxFileUpload上传时要先引用下面这个js

ajaxfileupload.js       代码如下:这个是网上下载的,不过我做了修改的。第一:下载下来的没有handleError这个方法,会报错;第二:在代码最后部分做了修改,不然不能成功,会报错,你拖到代码最下面就能看到。

引入顺序如图:(getPath()方法在commons.js中),最后一个是自己写的js,要在ajaxfileupload.js下面,不然无效,没用bootstrap不用管这个js,如果用了我的效果,这个必须。

用的时候你就新建一个ajaxfileupload.js ,把这个代码复制进去就可以了


jQuery.extend({

	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 ]);
		                }
		            },

		
    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 = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
        var oldElement = $('#' + fileElementId);
        var newElement = $(oldElement).clone();
        $(oldElement).attr('id', fileId);
        $(oldElement).before(newElement);
        $(oldElement).appendTo(form);
        //set attributes
        $(form).css('position', 'absolute');
        $(form).css('top', '-1200px');
        $(form).css('left', '-1200px');
        $(form).appendTo('body');
        return form;
    },
    addOtherRequestsToForm: function(form,data)
    {
        // add extra parameter
        var originalElement = $('<input type="hidden" name="" value="">');
        for (var key in data) {
            name = key;
            value = data[key];
            var cloneElement = originalElement.clone();
            cloneElement.attr({'name':name,'value':value});
            $(cloneElement).appendTo(form);
        }
        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 = new Date().getTime()
        var form = jQuery.createUploadForm(id, s.fileElementId);
        if ( s.data ) form = jQuery.addOtherRequestsToForm(form,s.data);
        var io = jQuery.createUploadIframe(id, s.secureuri);
        var frameId = 'jUploadFrame' + id;
        var formId = 'jUploadForm' + id;
        // Watch for a new set of requests
        if ( s.global && ! jQuery.active++ )
        {
            jQuery.event.trigger( "ajaxStart" );
        }
        var requestDone = false;
        // Create the request object
        var xml = {}
        if ( s.global )
            jQuery.event.trigger("ajaxSend", [xml, s]);
        // Wait for a response to come back
        var uploadCallback = function(isTimeout)
        {
            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 a local callback was specified, fire it and pass it the data
        
                        if ( s.success )
                            s.success( data, status );

                        // Fire the global callback
                        if( s.global )
                            jQuery.event.trigger( "ajaxSuccess", [xml, s] );
                    } else
                        jQuery.handleError(s, xml, status);
                } catch(e)
                {
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }

                // The request was completed
                if( s.global )
                    jQuery.event.trigger( "ajaxComplete", [xml, s] );

                // Handle the global AJAX counter
                if ( s.global && ! --jQuery.active )
                    jQuery.event.trigger( "ajaxStop" );

                // Process result
                if ( s.complete )
                    s.complete(xml, status);

                jQuery(io).unbind()

                setTimeout(function()
                {	try
                    {
                        $(io).remove();
                        $(form).remove();

                    } catch(e)
                    {
                        jQuery.handleError(s, xml, null, e);
                    }

                }, 100)

                xml = null

            }
        }
        // Timeout checker
        if ( s.timeout > 0 )
        {
            setTimeout(function(){
                // Check to see if the request is still happening
                if( !requestDone ) uploadCallback( "timeout" );
            }, s.timeout);
        }
        try
        {
            // var io = $('#' + frameId);
            var form = $('#' + formId);
            $(form).attr('action', s.url);
            $(form).attr('method', 'POST');
            $(form).attr('target', frameId);
            if(form.encoding)
            {
                form.encoding = 'multipart/form-data';
            }
            else
            {
                form.enctype = 'multipart/form-data';
            }
            $(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;
        
//        console.log("type--"+type);
        // If the type is "script", eval it in global context
        if ( type == "script" )
            jQuery.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
        {
        	//将从后台传过来的json格式的字符串转换成json返回,这是我改的地方
            data = eval("("+data+")");
        }
        // evaluate scripts within html
        if ( type == "html" )
            jQuery("<div>").html(data).evalScripts();
        //alert($('param', data).each(function(){alert($(this).attr('value'));}));
        console.log("data13:"+data);
        return data;
    }
})

js部分写完了,那么就到了后台servlet了

注意:在下面将是否上传成功的信息写回客户端是以json格式字符写回去,不是向客户端写回一个对象,那么就要用到相应的将对象转变为json的jar包,里面有个ObjectMapper类

如下:

servlet部分代码:

@WebServlet(urlPatterns="/upfile")
@MultipartConfig
public class FileUpUtil extends HttpServlet {

	private static final long serialVersionUID = 4728407898261233142L;
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");

		File file=new File("D:\\upFile");
		if(!file.exists()){//如果文件夹不存在
			file.mkdir();//创建文件夹
		}
		String path = "D:\\upFile";//该文件夹用于保存你的文件
	
		Collection<Part> names = req.getParts();//得到文件对象
		for (Part part : names) {
			if(part.getContentType() != null) {
				String header = part.getHeader("Content-Disposition");//获得请求头中Content-Disposition的内容,这里面包含文件的名字
				System.out.println(header);
				
				String fileName = getFileName(header);//得到文件名,自己写的拆分字符串方法
				System.out.println(fileName);
				
				String filePath = path + File.separator + fileName;
				
				ReqMessage data = new ReqMessage(true, "上传到服务器成功");//实例化返回消息
				try {
					part.write(filePath);//向目标位置写入真实文件
					part.delete();//删除临时文件
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
					data.setStatus(false);
					data.setInformation("系统繁忙,请稍后重试!");
				}
				
				ObjectMapper om = new ObjectMapper();
				String json = om.writeValueAsString(data);//将对象转变成json格式的字符串
				
				resp.setCharacterEncoding("utf-8");
				resp.setContentType("text/html;charset=utf-8");//设置返回后的格式
				PrintWriter out = resp.getWriter();
				out.println(json);//将信息以json格式返回
			}
		}	
	}
	
    //拆分字符串,获得文件名的方法
	private String getFileName(String header) {
		String[] strs = header.split(";");
		String[] tmpArrs = strs[2].split("=");
		String fileName = tmpArrs[1]; 
		return fileName.substring(1, fileName.length() - 1);
	}

}

代码中用到的一些自己写的bean文件,其实就一个ReqMessage,用于装返回信息的

代码如下:

public class ReqMessage implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2954844625138246393L;
	
	private boolean status;//保存状态
	private String information;//保存具体信息
	
	public ReqMessage() {
		super();
	}
	public ReqMessage(boolean status, String information) {
		super();
		this.status = status;
		this.information = information;
	}
	
	public boolean isStatus() {
		return status;
	}
	public void setStatus(boolean status) {
		this.status = status;
	}
	public String getInformation() {
		return information;
	}
	public void setInformation(String information) {
		this.information = information;
	}
	
	@Override
	public String toString() {
		return "ReqMessage [status=" + status + ", information=" + information + "]";
	}
	

}

那么写完了后,点击上传后会弹出来返回的这个信息

不是图片的其他文件上传的效果:

图片上传的效果:

上传成功后的效果:

猜你喜欢

转载自blog.csdn.net/IT_CREATE/article/details/85072591
今日推荐