記得前一段時間,為了研究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,具體配置方法如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize"> <value>104857600</value> </property> <property name="maxInMemorySize"> <value>4096</value> </property> </bean>
3 JSP檔案:
大家對form表單提交問價的方式很熟悉,但是我們有很多情況下並不能直接使用form表單方式直接提交。這時候我們就需要使用Ajax方式提交,Ajax有很多的好處,比如當我們不需要重新整理頁面獲希望進行局部重新整理的時候,我們就可以使用Ajax。下面是我的表單提交的JSP頁面,其中包含JS的詳細步驟和HTML檔案:
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ include file="../commons/taglibs.jsp"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>發布資訊</title> <script type="text/javascript" src="${ctx}/resources/new_js/jquery.js"></script> <script type="text/javascript" src="${ctx}/resources/js/ajaxfileupload.js"></script> <script type="text/javascript"> function save(){ var typeId = $("#type_span_info").attr("data-id"); if (typeof (typeId) == "undefined") { $("#type_p_info").show(); return; } else { $("#type_p_info").hide(); } var title = $("#title_input_info").val(); var summary = $("#summary_input_info").val(); var content = $("#content_textarea_info").val(); $.ajaxFileUpload({ url : "${ctx}/info/doUpload", secureuri : false,//是否需要安全性通訊協定 fileElementId : 'file', type : 'POST', //檔案提交的方式 dataType : 'string', cache : false, //是否進行頁面緩衝 async : true, // 是否同步提交 success : function(data) { $.ajax({ url : '${ctx}/info/addInfo?fileUrl='+data, type : 'post', data:{title:title,summary:summary,content:content,typeId:typeId}, async : false, success : function(result) { if (result == 1) { $("#del_prompt_p").text("添加成功"); fnError3(); } else if (result == 2) { $("#del_prompt_p").text("添加失敗") fnError2(); } else { $("#del_prompt_p").text("系統錯誤"); fnError2(); } } }); } }); } </script></head><body class="body_bg"><p class="main"> <!--頁面主體 start--> <p class="main_content"> <p class="later_index clear wrap"> <p class="later_right fr"> <p class="roll_parent" id="roll_parent"> <p class="scroll_parent" id="scroll_parent"> <p class="scroll" id="scroll"></p> </p> <p class="roll_son" id="roll_son"> <p class="later_content later_content1"> <p class="release_name"> <h3> <span>發布資訊</span> </h3> </p> <p class="issue_content"> <form action="" id="form1" method="post" enctype="multipart/form-data"> <table class="issue_tab"> <tbody> <tr> <td><p><i>*</i><strong>標題</strong></p> </td> </tr> <tr> <td><input id="title_input_info" name="title_input_info" type="text" placeholder="最多可以輸入40個字" type="text" maxlength="40"/> <!-- <span class="colse"></span> --> <p class="colse_tip"></p> <!-- <p class="colse_tip" id="title_p_info" style="display:hidden;">請選擇標題!</p> --> </td> </tr> <tr> <td><p><i>*</i><strong>摘要</strong></p></td> </tr> <tr> <td><input name="summary_input_info" id="summary_input_info" type="text" placeholder="最多可以輸入100個字" type="text" maxlength="100" /> <p class="colse_tip"></p></td> </tr> <tr> <td><p><i>*</i><strong>內容</strong></p> </td> </tr> <tr> <td><textarea name="content_textarea_info" id="content_textarea_info"></textarea> <p class="colse_tip"></p></td> </tr> <tr> <td><p><i>*</i><strong>選擇行業</strong></p> <p class="colse_tip" id="type_p_info" style="display:hidden;">請選擇行業!</p></td> </tr> <tr> <td> <p class="next_select select_width select_bg" id="next_select0"> <span id="type_span_info">請選擇</span> </p> <p class="select_box select_top select_width" data-id="" id="select_box0"> <ul> <li class="curr" data-id="2">化工</li> <li data-id="3">裝備製造</li> <li data-id="4">生物醫藥</li> <li data-id="5">電子資訊</li> <li data-id="6">其他</li> </ul> </p> </td> </tr> <tr> <td> <input type="button" class="isue_inp_btn" value="添加圖片"/> <input type="text" id="issue_input_text" class="issue_text" /> <input type="file" id="file" name="file" class="issue_file" onchange="javaScript:validate_img(this)" /> </td> </tr> </tbody> </table> </form> </p> <p class="financial_pro_icon"> <p class="financial_pro_icon_l issue_btn1"> <a href="javaScript:save();">發布</a> </p> <p class="financial_pro_icon_r issue_btn1"> <a href="${ctx}/info/gotoInfo?index=2">取消</a> </p> </p> </p> </p> </p> </p> </p> </p> <!--頁面主體 end--></p></body></html>
上面的代碼是我在項目實際開發的過程中所用的代碼,具體的CSS檔案與JS檔案我已經刪掉了,但是不會影響具體的操作,大家使用的時候只需要把其中的class檔案刪掉了就可以了。好了,我們在說一說上面的代碼。首先為大家解釋一下ctx的作用,在我們項目開發的過程中,我們要求必須使用絕對路徑,所有{ctx}是我們封裝好的一個東西,就是我們的伺服器位址+連接埠號碼+項目名稱。當我們使用的時候,只需要引用一下檔案,就是上面直接使用的<%@ include file=”../commons/taglibs.jsp”%>,當我們用的時候直接使用${ctx}就可以,大家在使用的時候就直接使用自己的本機地址連接埠號碼與項目名稱就可以。後面的/resources/new_js/jquery.js就是我們要使用的jqery.js檔案的存放地址。
其實在上面的Ajax的操作中,我相當於做了兩次的Ajax的提價,但是在第一次提交的時候,後台給我們返回一個參數,就是我們的檔案存放路徑與檔案名稱,在第二次提交的時候,我們將這些參數與其他參數同時上傳到後台,並將這些參數儲存到資料庫中,以便我們使用。
* 4 後台代碼:
//檔案上傳@RequestMapping(value = "/doUpload", method = RequestMethod.POST, produces = "text/html; charset=UTF-8")@ResponseBody public String doUpload(HttpServletRequest request, HttpServletResponse response) throws IOException { List<String> fileNames = null; if (request instanceof MultipartHttpServletRequest) { // process the uploaded file logger.info("=====進入檔案類型選擇====="); fileNames = uploadAttachment(request, "file"); } String url = ""; if (fileNames.size() > 0) { for (int i = 0; i < fileNames.size(); i++) { url = url + fileNames.get(i); if(i < fileNames.size() - 1){ url = url + ","; } } } return url; } //檔案上傳的工具類public List<String> uploadAttachment(HttpServletRequest request, String type) throws IOException { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; List<MultipartFile> files = multipartRequest.getFiles(type); logger.info("資料長度========>>>>>>>>>>" + files.size()); Calendar now = Calendar.getInstance(); int year = now.get(Calendar.YEAR); int month = now.get(Calendar.MONTH) + 1; String realPath = PropertiesUtil.getProperty("realPath"); System.err.println("realpath=====>>>>>" + realPath); //String savePath = request.getSession().getServletContext().getRealPath("/") + "p_image\\" + type + "\\" + year+ "\\" + month + "\\"; String savePath = "government"+ File.separator + "image"+ File.separator + year+ File.separator + month + File.separator; logger.info("儲存路徑=====>" + savePath); List<String> fileNames = new ArrayList<String>(); for (MultipartFile multipartFile : files) { logger.info("--" + multipartFile.getOriginalFilename()); String fileName = multipartFile.getOriginalFilename(); String prefix = fileName.substring(fileName.lastIndexOf(".") + 1); String custName = "" + System.currentTimeMillis() + "." + prefix; if (UsedUtil.isNotNull(fileName)) { File targetFile = new File(realPath+savePath, custName); // fileName = year+"-"+month+"-"+fileName; if (!targetFile.exists()) { targetFile.mkdirs(); multipartFile.transferTo(targetFile); } try { } catch (Exception e) { e.printStackTrace(); } fileNames.add(savePath + custName); } } return fileNames; }//添加諮詢@RequestMapping(value = "/addInfo", method = RequestMethod.POST)@ResponseBody public Integer addInfo(HttpServletRequest request, HttpServletResponse response, @RequestParam String fileUrl) { InfoBean bean = new InfoBean(); if(UsedUtil.isNotNull(fileUrl)){ bean.setImagePath(fileUrl); } Map<String, Object> paramMap = ControllerUtil.request2Map(request); bean.setTitle((String) paramMap.get("title")); bean.setSummary((String) paramMap.get("summary")); bean.setContent((String) paramMap.get("content")); bean.setTypeId((String)paramMap.get("typeId")); return infoService.insInfo(bean); }
在上面的代碼中我們可以看到,在檔案第一次上傳的過程中,我們首先進入到doUpload中,然後使用uploadAttachment工具類,並將檔案上傳到伺服器中,在上傳的過程中,我首先做了一個檔案唯一名稱的操作,就是擷取目前時間的毫秒數,雖然不能絕對保證,但是到並發量小的時候可以保證不會造成檔案名稱重複。然後,我將檔案上傳的路徑的上傳地址寫到了.properties中,這樣的好處是當我們想更換檔案上傳的路徑時,我們就可以直接修改.properties檔案,而讀取.properties檔案的具體方式在我的另一篇文章中講到。最後,我們在開發的過程中,檔案儲存一般是儲存到檔案伺服器中,而檔案伺服器一般是在Linux中,而在不同的伺服器中,路徑是使用斜杠還是反斜線是不同的,所有我在這裡面使用了File.separator來代替,File.separator在不同的系統中可以自動產生斜杠獲反斜線。