如何實現java webApp異步上傳圖片,先了解以下幾個問題:
1.圖片上傳;
2.圖片上傳預覽;
3.上傳圖片更改地址異步添加到數據庫;
主要內容<br />本示例主要採用純HTML前端和JavaScript代碼作工具,查詢有關demo其實現圖片上傳的代碼範例如下:
(1)點擊上傳圖片的div代碼:
<div id="div1"> <input type="file" id="choose" accept="image/*" multiple > <a id="upload">上傳圖片</a> <a onclick="selectphoto();">從圖庫中選擇</a> <a id="back">取消</a></div>
(2)javaScript代碼
<script type="text/javascript"> //獲取上傳圖片的input表單元素var filechooser = document.getElementById("choose"); //創建用於壓縮圖片的canvas var canvas = document.createElement("canvas"); //獲取canvas的視覺屬性var ctx = canvas.getContext('2d'); //瓦片canva var tCanvas = document.createElement("canvas"); var tctx = tCanvas.getContext("2d"); //畫布的大小var maxsize = 100 * 1024; //上傳圖片點擊事件$("#upload").on("click", function() { filechooser.click(); }) .on("touchstart", function() { //添加元素屬性$(this).addClass("touch"); }) .on("touchend", function() { //移除元素屬性$(this).removeClass("touch"); }); //元素改變filechooser.onchange = function() { //如果選擇為空,返回操作if (!this.files.length) return; //創建上傳圖片的數組var files = Array.prototype.slice.call(this.files); //選擇為數量大於1張時,反回操作,這裡根據需求設定;pc端測試一次可以上傳若干張圖片,移動端選擇一張,頁面只能預覽一張。由於是移動端,所以作此判斷。 if (files.length >1) { alert("一次只能上傳1張圖片"); return; } //遍歷上傳圖片的文件數組,可不用遍歷,直接取即可。 files.forEach(function(file, i) { //判斷圖片格式if (!///(?:jpeg|png|gif)/i.test(file.type)) return; var reader = new FileReader(); var li = document.createElement("li");// 獲取圖片大小var size = file.size / 1024 > 1024 ? (~~(10 * file.size / 1024 / 1024)) / 10 + "MB" : ~~(file.size / 1024) + "KB"; //圖片預覽li.innerHTML = '<div><span></span></div><div>' + size + '</div>'; //追加圖片預覽代碼; $(".img-list").append($(li)); reader.onload = function() { var result = this.result; var img = new Image(); img.src = result; //圖片顯示$(li).css("background-image", "url(" + result + ")"); //如果圖片大小小於100kb,則直接上傳if (result.length <= maxsize) { img = null; upload(result, file.type, $(li)); return; }// 圖片加載完畢之後進行壓縮,然後上傳if (img.complete) { callback(); } else { img.onload = callback; } function callback() { var data = compress(img); upload(data, file.type, $(li)); img = null; } }; reader.readAsDataURL(file); }); }; //以下是圖片壓縮相關; //使用canvas對大圖片進行壓縮function compress(img) { var initSize = img.src.length; var width = img.width; var height = img.height; //如果圖片大於四百萬像素,計算壓縮比並將大小壓至400萬以下var ratio; if ((ratio = width * height / 4000000) > 1) { ratio = Math.sqrt(ratio); width /= ratio; height /= ratio; } else { ratio = 1; } canvas.width = width; canvas.height = height; //鋪底色ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); //如果圖片像素大於100萬則使用瓦片繪製var count; if ((count = width * height / 1000000) > 1) { count = ~~(Math.sqrt(count) + 1); //計算要分成多少塊瓦片// 計算每塊瓦片的寬和高var nw = ~~(width / count); var nh = ~~(height / count); tCanvas.width = nw; tCanvas.height = nh; for (var i = 0; i < count; i++) { for (var j = 0; j < count; j++) { tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); } } } else { ctx.drawImage(img, 0, 0, width, height); } //進行最小壓縮var ndata = canvas.toDataURL('image/jpeg', 0.1); console.log('壓縮前:' + initSize); console.log('壓縮後:' + ndata.length); console.log('壓縮率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%"); tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; return ndata; } //圖片上傳,將base64的圖片轉成二進制對象,塞進formdata上傳function upload(basestr, type, $li) { var text = window.atob(basestr.split(",")[1]); var buffer = new Uint8Array(text.length); var pecent = 0, loop = null; for (var i = 0; i < text.length; i++) { buffer[i] = text.charCodeAt(i); } var blob = getBlob([buffer], type); var xhr = new XMLHttpRequest(); var formdata = getFormData(); formdata.append('upload', blob); //異步請求kindeditor插件的上傳圖片jsp頁面xhr.open('post', '<%=request.getContextPath()%>/kindeditor/jsp/upload_json.jsp'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { //返回服務器端的圖片地址var face_img=xhr.responseText; var id=$("#arId").text(); //異步像數據庫中添加圖片$.ajax({ type:"POST", //異步請求Struts的action類將圖片地址插入數據庫url:"add_article_faceurl.action", dataType:"json", data:"faceurl="+face_img+"&id="+id, async:true, success: function(msg){ //取添加數據庫中的圖片相關的id值,存入頁面隱藏區域$("#arId").text(msg); }, error: function(a){} }); } }; //模擬上傳進度顯示//數據發送進度,前50%展示該進度xhr.upload.addEventListener('progress', function(e) { if (loop) return; pecent = ~~(100 * e.loaded / e.total) / 2; $li.find(".progress span").css('width', pecent + "%"); if (pecent == 50) { mockProgress(); } }, false); //數據後50%用模擬進度function mockProgress() { if (loop) return; loop = setInterval(function() { pecent++; $li.find(".progress span").css('width', pecent + "%"); if (pecent == 99) { clearInterval(loop); } }, 100); } xhr.send(formdata); } /** * 獲取blob對象的兼容性寫法* @param buffer * @param format * @returns {*} */ function getBlob(buffer, format) { try { return new Blob(buffer, {type: format}); } catch (e) { var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder); buffer.forEach(function(buf) { bb.append(buf); }); return bb.getBlob(format); } } /** * 獲取formdata */ function getFormData() { var isNeedShim = ~navigator.userAgent.indexOf('Android') && ~navigator.vendor.indexOf('Google') && !~navigator.userAgent.indexOf('Chrome') && navigator.userAgent.match(/AppleWebKit//(/d+)/).pop() <= 534; return isNeedShim ? new FormDataShim() : new FormData(); } /** * formdata 補丁, 給不支持formdata上傳blob的android機打補丁* @constructor */ function FormDataShim() { console.warn('using formdata shim'); var o = this, parts = [], boundary = Array(21).join('-') + (+new Date() * (1e16 * Math.random())).toString(36), oldSend = XMLHttpRequest.prototype.send; this.append = function(name, value, filename) { parts.push('--' + boundary + '/r/nContent-Disposition: form-data; name="' + name + '"'); if (value instanceof Blob) { parts.push('; filename="' + (filename || 'blob') + '"/r/nContent-Type: ' + value.type + '/r/n/r/n'); parts.push(value); } else { parts.push('/r/n/r/n' + value); } parts.push('/r/n'); }; // Override XHR send() XMLHttpRequest.prototype.send = function(val) { var fr, data, oXHR = this; if (val === o) { // Append the final boundary string parts.push('--' + boundary + '--/r/n'); // Create the blob data = getBlob(parts); // Set up and read the blob into an array to be sent fr = new FileReader(); fr.onload = function() { oldSend.call(oXHR, fr.result); }; fr.onerror = function(err) { throw err; }; fr.readAsArrayBuffer(data); // Set the multipart content type and boudary this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); XMLHttpRequest.prototype.send = oldSend; } else { oldSend.call(this, val); } }; }</script>(3)kindeditor插件的上傳圖片jsp頁面相關代碼.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ page import="java.util.*,java.io.*" %><%@ page import="java.text.SimpleDateFormat" %><%@ page import="org.apache.commons.fileupload.*" %><%@ page import="org.apache.commons.fileupload.disk.*" %><%@ page import="org.apache.commons.fileupload.servlet.*" %><%@ page import="org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper"%><%@ page import="org.json.simple.*" %><%/** * KindEditor JSP * * 本JSP程序是演示程序,建議不要直接在實際項目中使用。 * 如果您確定直接使用本程序,使用之前請仔細確認相關安全設置。 * *///文件保存目錄路徑String savePath = pageContext.getServletContext().getRealPath("/") + "attached/";//String savePath = "http:////192.168.1.226:8080//qslnbase//uploadFile/";//String savePath = "D:/WWW/qslnADP/ADP/WebRoot/kindeditor/attached/";//文件保存目錄URLString saveUrl = request.getContextPath() + "/attached/";//定義允許上傳的文件擴展名HashMap<String, String> extMap = new HashMap<String, String>();extMap.put("image", "gif,jpg,jpeg,png,bmp,blob");extMap.put("flash", "swf,flv");extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");//最大文件大小long maxSize = 1000000;response.setContentType("text/html; charset=UTF-8");if(!ServletFileUpload.isMultipartContent(request)){ out.println(getError("請選擇文件。")); return;}//檢查目錄File uploadDir = new File(savePath);if(!uploadDir.isDirectory()){ out.println(getError("上傳目錄不存在。")); return;}//檢查目錄寫權限if(!uploadDir.canWrite()){ out.println(getError("上傳目錄沒有寫權限。")); return;}String dirName = request.getParameter("dir");if (dirName == null) { dirName = "image";}if(!extMap.containsKey(dirName)){ out.println(getError("目錄名不正確。 ")); return;}//創建文件夾savePath += dirName + "/";saveUrl += dirName + "/";File saveDirFile = new File(savePath);if (!saveDirFile.exists()) { saveDirFile.mkdirs();}SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");String ymd = sdf.format(new Date());savePath += ymd + "/";saveUrl += ymd + "/";File dirFile = new File(savePath);if (!dirFile.exists()) { dirFile.mkdirs();}//Struts2 請求包裝過濾器MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) request;//獲得上傳的文件名String fileName1 = wrapper.getFileNames("upload")[0];//獲得文件過濾器File file = wrapper.getFiles("upload")[0];//檢查文件大小if(file.length() > maxSize){ out.println(getError("上傳文件大小超過限制。")); return;}//檢查擴展名String fileExt1 = fileName1.substring(fileName1.lastIndexOf(".") + 1).toLowerCase();//重構上傳文件名SimpleDateFormat df1 = new SimpleDateFormat("yyyyMMddHHmmss");String newFileName1 = df1.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt1;byte[] buffer = new byte[1024];//獲取文件輸出流FileOutputStream fos = new FileOutputStream(savePath + newFileName1);String url=savePath + newFileName1;out.println(url);//獲取內存中當前文件輸入流InputStream in = new FileInputStream(file);try { int num = 0; while ((num = in.read(buffer)) > 0) { fos.write(buffer, 0, num); }} catch (Exception e) { e.printStackTrace(System.err);} finally { in.close(); fos.close();}%><%!private String getError(String message) { JSONObject obj = new JSONObject(); obj.put("error", 1); obj.put("message", message); return obj.toJSONString();}%> ( 4)有關kindeditor上傳圖片的jar包有如下所示
A.commons-fileupload-1.2.1.jar
B.commons-io-1.4.jar
C.json_simple-1.1.jar
這裡沒有用到有關於kindeditor的js代碼,具體可參考:Kindeditor實現圖片自動上傳功能
(5)有關kindeditor上傳圖片預覽的div如下
<div id="div2"> <ul> <li id="wy"> <img style="height:100%;width:100%;position:absolute;top:0px;" src="<%=request.getContextPath()%>/shequ/images/index.png;" > </li> </ul> </div>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。