015-图片文件上传
1. 通常情況下, 我們上傳文件是借助type="file"的input標(biāo)簽來完成的。layui圖片/文件上傳, 它所包含的強(qiáng)勁的功能, 還有靈活的UI。任何元素都可以作為上傳組件來調(diào)用, 譬如: 按鈕、圖片、普通的DIV等等, 而不再是一個單調(diào)的file文件域。
2. 模塊加載名稱: upload。
3. 核心方法與基礎(chǔ)參數(shù)選項
3.1. 使用upload模塊必須與upload.render(options)方法打交道, 其中的options即為基礎(chǔ)參數(shù), 它是一個對象。
4. options參數(shù)詳見下表:
5. 服務(wù)端上傳接口
5.1. 設(shè)定一個URL地址給url參數(shù), 用來告訴upload模塊的服務(wù)端上傳接口。像你平時使用Ajax一樣。
upload.render({elem: '#uploadImage' // 指向容器選擇器,url: 'fu.action' // 必填項, 服務(wù)端上傳接口,method: 'post' // 可選項, HTTP類型, 默認(rèn)post,data: {uploadType: 1} // 可選項, 請求上傳接口的額外參數(shù) });5.2. 該接口返回的相應(yīng)信息(response)必須是一個標(biāo)準(zhǔn)的JSON格式。
6. 選擇文件的回調(diào)函數(shù) - choose
6.1. choose回調(diào)在文件被選擇后觸發(fā), 該回調(diào)會在before回調(diào)之前。一般用于非自動上傳(即auto: false)的場景, 比如: 預(yù)覽圖片等。
choose: function(obj){ // 預(yù)讀本地文件, 如果是多文件, 則會遍歷。obj.preview(function(index, file, result){console.log(index); // 得到文件索引console.log(file); // 得到文件對象console.log(result); // 得到文件base64編碼, 比如圖片var reader = new FileReader();reader.readAsDataURL(file);document.getElementById('preview').src = result;}); }6.2. choose回調(diào)函數(shù)的obj參數(shù)有4個方法:
// 將每次選擇的文件追加到文件隊列 var files = obj.pushFile();// 預(yù)讀本地文件, 如果是多文件, 則會遍歷。 obj.preview(function(index, file, result){obj.resetFile(index, file, '123.jpg'); // 重命名文件名// 重新上傳方法obj.upload(index, file); }7. 文件上傳前的回調(diào)函數(shù) - before
7.1. before回調(diào)在choose回調(diào)之后、done/error回調(diào)之前觸發(fā)。返回的參數(shù)完全類似choose回調(diào)。一般用于上傳完畢前的loading、圖片預(yù)覽等。
upload.render({elem: '#uploadFile',url: 'fu.action',accept: 'file',exts: 'zip|rar|7z',before: function(obj){layer.load(); // 上傳loading},done: function(res, index, upload){alert('上傳完畢回調(diào)' + res.code);layer.closeAll('loading'); // 關(guān)閉loading},error: function(index, upload){alert('請求異常回調(diào)');layer.closeAll('loading'); // 關(guān)閉loading} });8. 上傳接口請求完成的回調(diào)函數(shù) - done
8.1. 在上傳接口請求完畢后觸發(fā), 但文件不一定是上傳成功的, 只是接口的響應(yīng)狀態(tài)正常(200)。回調(diào)返回三個參數(shù), 分別為: 服務(wù)端響應(yīng)信息、當(dāng)前文件的索引、重新上傳的方法:
done: function(res, index, upload){alert('上傳完畢回調(diào)'); }9. 上傳請求失敗的回調(diào)函數(shù) - done
9.1. 當(dāng)請求上傳時出現(xiàn)異常時觸發(fā)(如網(wǎng)絡(luò)異常、404/500等)。回調(diào)返回兩個參數(shù), 當(dāng)前文件的索引、重新上傳的方法:
error: function(index, upload){alert('請求異常回調(diào)'); }10. 多文件上傳完畢后的狀態(tài)回調(diào)函數(shù) - allDone
10.1. 只有當(dāng)開啟多文件時(即multiple: true), 該回調(diào)才會被觸發(fā)。回調(diào)返回一個object類型的參數(shù), 包含一些狀態(tài)數(shù)據(jù):
allDone: function(obj){ // 當(dāng)文件全部被提交后, 才觸發(fā)console.log(obj.total); // 得到總文件數(shù)console.log(obj.successful); // 請求成功的文件數(shù)console.log(obj.aborted); // 請求失敗的文件數(shù) }11. 文件上傳進(jìn)度的回調(diào)函數(shù) - progress
11.1. 在網(wǎng)速一般的情況下, 大文件的上傳通常需要一定時間的等待, 而瀏覽器并不會醒目地告知你它正在努力地上傳中, 此時為了提升用戶體驗, 我們可以通過該回調(diào)制作一個進(jìn)度條。
progress: function(n, elem){var percent = n + '%' // 獲取進(jìn)度百分比element.progress('progress', percent); // 可配合 layui進(jìn)度條元素使用console.log(elem); // 得到當(dāng)前觸發(fā)的元素 DOM對象。可通過該元素定義的屬性值匹配到對應(yīng)的進(jìn)度條。 }12. 重載實例
12.1. 有時你可能需要對upload.render()實例進(jìn)行重載, 通過改變一些參數(shù)(如將上傳文件重置為只上傳圖片等場景)來重置功能。如:
// 創(chuàng)建一個實例 var uploadInst = upload.render({elem: '#id',url: '/api/upload/',size: 1024*5 // 限定大小 });// 重載該實例,支持重載全部基礎(chǔ)參數(shù) uploadInst.reload({accept: 'images' // 只允許上傳圖片,acceptMime: 'image/*' // 只篩選圖片,size: 1024*2 // 限定大小 });13. 重新上傳
13.1. 在執(zhí)行upload.render(options)方法時, 其實有返回一個實例對象, 以便對完成重新上傳等操作。注意: 這是對當(dāng)前上傳隊列的全局重新上傳, 而choose回調(diào)返回的obj.upload(index, file) 方法則是對單個文件進(jìn)行重新上傳。
var uploadInst = upload.render({elem: '#id',url: '/api/upload/',choose: function(obj){obj.preview(function(index, file, result){// 對上傳失敗的單個文件重新上傳, 一般在某個事件中使用obj.upload(index, file);});} });// 重新上傳的方法, 一般在某個事件中使用 uploadInst.upload();14. 例子
14.1. 新建一個動態(tài)的web工程-UploadLayui
14.2. 把layui拷貝到WebContent目錄下
14.3. 編寫upload.html
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>圖片文件上傳 - layui</title><link rel="stylesheet" href="layui/css/layui.css"><script type="text/javascript" src="layui/layui.js"></script></head><body><button type="button" class="layui-btn" id="selectImage"><i class="layui-icon"></i>選擇圖片</button> <button type="button" class="layui-btn" lay-active="uploadImage" ><i class="layui-icon"></i>上傳圖片</button><br /><br /><img id="preview" src="" alt="預(yù)覽圖片" /> <br /><br /><button type="button" class="layui-btn" id="uploadFile"><i class="layui-icon"></i>多文件上傳</button> <br /><br /><div lay-filter="progress" class="layui-progress layui-progress-big" lay-showPercent="true"><div class="layui-progress-bar layui-bg-blue" lay-percent="0%"></div></div><br /><br /><script type="text/javascript">layui.use(['util', 'element', 'layer', 'upload'], function() {var upload = layui.upload,element = layui.element,layer = layui.layer,util = layui.util;var uploadInst = upload.render({elem: '#selectImage' // 指向容器選擇器,url: 'fu.action' // 服務(wù)端上傳接口,data: {uploadType: 1} // 請求上傳接口的額外參數(shù),accept: 'images' // 指定允許上傳時校驗的文件類型,acceptMime: 'image/jpg, image/png' // 規(guī)定打開文件選擇框時, 篩選出的文件類型,exts: 'jpg|png' // 允許上傳的文件后綴,auto: false // 是否選完文件后自動上傳,field: 'myphoto' // 設(shè)定文件域的字段名,size: 1024 * 20 // 設(shè)置文件最大可允許上傳的大小, 單位 KB,drag: true // 是否接受拖拽的文件上傳,choose: function(obj){ // 預(yù)讀本地文件, 如果是多文件, 則會遍歷。obj.preview(function(index, file, result){console.log(index); // 得到文件索引console.log(file); // 得到文件對象console.log(result); // 得到文件base64編碼, 比如圖片var reader = new FileReader();reader.readAsDataURL(file);document.getElementById('preview').src = result;});}// 執(zhí)行上傳請求后的回調(diào)。返回三個參數(shù), 分別為: res(服務(wù)端響應(yīng)信息)、index(當(dāng)前文件的索引)、upload(重新上傳的方法, 一般在文件上傳失敗后使用)。,done: function(res, index, upload){alert('上傳完畢回調(diào)' + res.code);}// 執(zhí)行上傳請求出現(xiàn)異常的回調(diào)(一般為網(wǎng)絡(luò)異常、404等)。返回兩個參數(shù), 分別為: index(當(dāng)前文件的索引)、upload(重新上傳的方法)。,error: function(index, upload){// 請求異常回調(diào)alert('請求異常回調(diào)');}});util.event('lay-active', {uploadImage: function() {uploadInst.upload(); }});upload.render({elem: '#uploadFile',url: 'fu.action',data: {uploadType: 2},accept: 'file',acceptMime: '*',exts: 'zip|rar|7z',auto: true,field: 'enclosure' ,size: 1024 * 200,drag: true,multiple: true,number: 5,before: function(obj){layer.load(); // 上傳loading},progress: function(n, elem){var percent = n + '%' // 獲取進(jìn)度百分比element.progress('progress', percent); // 可配合 layui進(jìn)度條元素使用console.log(elem); // 得到當(dāng)前觸發(fā)的元素 DOM對象。可通過該元素定義的屬性值匹配到對應(yīng)的進(jìn)度條。},done: function(res, index, upload){alert('上傳完畢回調(diào)' + res.code);layer.closeAll('loading'); // 關(guān)閉loading},allDone: function(obj){ // 當(dāng)文件全部被提交后, 才觸發(fā)console.log(obj.total); // 得到總文件數(shù)console.log(obj.successful); // 請求成功的文件數(shù)console.log(obj.aborted); // 請求失敗的文件數(shù)},error: function(index, upload){alert('請求異常回調(diào)');layer.closeAll('loading'); // 關(guān)閉loading}});}); </script></body> </html>14.4. 拷貝上傳文件和谷歌json的相關(guān)jar
14.5. 編寫FdData.java實體類
package com.layui.upload;import java.io.Serializable;public class FdData implements Serializable {private static final long serialVersionUID = 1L;private String src;public FdData(String src) {super();this.src = src;}public String getSrc() {return src;}public void setSrc(String src) {this.src = src;} }14.6. 編寫FdRes.java實體類
package com.layui.upload;import java.io.Serializable; import java.util.List;public class FdRes implements Serializable {private static final long serialVersionUID = 1L;private int code;private String msg;private List<FdData> datas;public FdRes(int code, String msg, List<FdData> datas) {super();this.code = code;this.msg = msg;this.datas = datas;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public List<FdData> getDatas() {return datas;}public void setDatas(List<FdData> datas) {this.datas = datas;} }14.7. 編寫上傳文件接口
package com.layui.upload;import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.google.gson.Gson;public class FileUpload extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 創(chuàng)建一個磁盤文件的工廠, 然后將它傳遞到servletFileUplaod的實例中DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);// 根據(jù)request對象獲取所有的文件集合, 這里包括input標(biāo)簽輸入的值也屬于FileInputtry {List<FileItem> fileItemList = servletFileUpload.parseRequest(req);Iterator<FileItem> iterator = fileItemList.iterator();while (iterator.hasNext()) {FileItem fileItem = (FileItem) iterator.next();if (fileItem.isFormField()) { // 是否是表單提交域, 可以分區(qū)是否上傳的附件String name = fileItem.getFieldName(); // input標(biāo)簽的nameString value = fileItem.getString(); // input表單的valueSystem.out.println("name = " + name + ", value= " + value);} else {String fieldName = fileItem.getFieldName(); // 表單提交過來的file input標(biāo)簽中name的屬性值String fileName = fileItem.getName(); // file input上傳的文件名String contentType = fileItem.getContentType(); // 獲得上傳文件的類型long size = fileItem.getSize(); // 上傳文件的大小String filePath = getServletContext().getRealPath("/") + fileName;File saveFile = new File(filePath);fileItem.write(saveFile); // 將文件寫入磁盤中System.out.println("filePath = " + filePath + ", size= " + size + ", contentType= " + contentType + ", fieldName= " + fieldName);FdData fdData = new FdData(filePath);List<FdData> datas = new ArrayList<FdData>();datas.add(fdData);FdRes fdRes = new FdRes(1, "上傳成功", datas);Gson gson = new Gson();String json = gson.toJson(fdRes);// 響應(yīng)客戶端的內(nèi)容類型是text/html 編碼是UTF-8(包含字符編碼和網(wǎng)頁編碼)resp.setHeader("Content-Type", "text/html; charset=UTF-8");resp.getWriter().println(json);}}} catch (Exception e) {e.printStackTrace();}}protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException ,IOException {doGet(req, resp);}; }14.8. 配置web.xml
14.9. 效果圖
總結(jié)
以上是生活随笔為你收集整理的015-图片文件上传的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。