1. 程式人生 > >基於WebUploader的檔案上傳外掛

基於WebUploader的檔案上傳外掛

首先把地址甩出來,http://fex-team.github.io/webuploader/

裡面有比較完整的demo案例文件,本文主要是基於檔案上傳和圖片上傳增加了大量的註釋,基本保證了每行程式碼都有註釋以助於理解,是對官網demo的增強版,希望可以幫助大家更好的理解該外掛

首先是檔案上傳

jQuery(function() {
    var $ = jQuery,
        $list = $('#thelist'),
        $btn = $('#ctlBtn'),
        state = 'pending',
        uploader;

	//初始化,實際上可直接訪問Webuploader.upLoader
    uploader = WebUploader.create({

        // 不壓縮image
        resize: false,

        // swf檔案路徑
        swf: BASE_URL + '/js/Uploader.swf',

        // 傳送給後臺程式碼進行處理,儲存到伺服器上
        server: 'http://webuploader.duapp.com/server/fileupload.php',

        // 選擇檔案的按鈕。可選。
        // 內部根據當前執行是建立,可能是input元素,也可能是flash.
        pick: '#picker'
    });

    // uploader新增事件,當檔案被加入佇列後觸發
    uploader.on( 'fileQueued', function( file ) {
		//在加入佇列時,建立一個樣式,供後面上傳成功失敗等等呼叫,定義一個*p表示指向該事件樣式
        $list.append( '<div id="' + file.id + '" class="item">' +
            '<h4 class="info">' + file.name + '</h4>' +
            '<p class="state">等待上傳...</p>' +
        '</div>' );
    });

    // 檔案上傳過程中觸發,攜帶上傳進度,file表示上傳的檔案,percentage表示上傳的進度
    uploader.on( 'uploadProgress', function( file, percentage ) {
		//定義一個變數名建立進度模組
        var $li = $( '#'+file.id ),
			//找到$li下class為progress的,並定義為$percent------為什麼先尋找在建立
            $percent = $li.find('.progress .progress-bar');

        //如果$percent沒值,就建立進度條加入到對應的檔名下, 避免重複建立
        if ( !$percent.length ) {
            $percent = $('<div class="progress progress-striped active">' +
              '<div class="progress-bar" role="progressbar" style="width: 0%">' +
              '</div>' +
            '</div>').appendTo( $li ).find('.progress-bar');
        }
		
		//為進度模組新增彈出文字
        $li.find('p.state').text('上傳中');
		
		//為進度模組建立讀條的百分比
        $percent.css( 'width', percentage * 100 + '%' );
    });

	//uploader觸發事件,當上傳成功事呼叫這個事件
    uploader.on( 'uploadSuccess', function( file ) {
		//呼叫檔案被加入時觸發的事件,findstate,並新增文字為已上傳
        $( '#'+file.id ).find('p.state').text('已上傳');
    });

	//uploader觸發事件,當上傳失敗時觸發該事件
    uploader.on( 'uploadError', function( file ) {
		//呼叫檔案被加入時觸發的事件,findstate,並新增文字為上傳出錯
        $( '#'+file.id ).find('p.state').text('上傳出錯');
    });
	
	//該事件表示不管上傳成功還是失敗都會觸發該事件
    uploader.on( 'uploadComplete', function( file ) {
		//呼叫
        $( '#'+file.id ).find('.progress').fadeOut();
    });

	//這是一個特殊事件,所有的觸發都會響應到,type的作用是記錄當前是什麼事件在觸發,並給state賦值
    uploader.on( 'all', function( type ) {
        if ( type === 'startUpload' ) {
            state = 'uploading';
        } else if ( type === 'stopUpload' ) {
            state = 'paused';
        } else if ( type === 'uploadFinished' ) {
            state = 'done';
        }
		
		//根據state判斷彈出文字
        if ( state === 'uploading' ) {
            $btn.text('暫停上傳');
        } else {
            $btn.text('開始上傳');
        }
    });
	
	//當按鈕被點選時觸發,根據狀態開始上傳或是暫停
    $btn.on( 'click', function() {
        if ( state === 'uploading' ) {
            uploader.stop();
        } else {
            uploader.upload();
        }
    });
});

然後是圖片上傳
jQuery(function() {

	//將jquery賦值給一個全域性的變數
    var $ = jQuery,

        $list = $('#fileList'),
        // 優化retina, 在retina下這個值是2,裝置畫素比
        ratio = window.devicePixelRatio || 1,

        // 縮圖大小
        thumbnailWidth = 100 * ratio,
        thumbnailHeight = 100 * ratio,

        // Web Uploader例項
        uploader;

    // 初始化Web Uploader
    uploader = WebUploader.create({

        // 自動上傳。
        auto: true,

        // swf檔案路徑
        swf: BASE_URL + '/js/Uploader.swf',

        // 檔案接收服務端。呼叫程式碼,把圖片儲存在伺服器端
        server: 'http://webuploader.duapp.com/server/fileupload.php',

        // 選擇檔案的按鈕。可選。
        // 內部根據當前執行是建立,可能是input元素,也可能是flash.
        pick: '#filePicker',

        // 只允許選擇檔案,可選。
        accept: {
            title: 'Images',
            extensions: 'gif,jpg,jpeg,bmp,png',
            mimeTypes: 'image/*'
        }
    });

    // 當有檔案新增進來的時候觸發這個事件
    uploader.on( 'fileQueued', function( file ) {
		//定義變數li
        var $li = $(
				//建立一個id
                '<div id="' + file.id + '" class="file-item thumbnail">' +
                    '<img>' +
					//建立一個為info的class
                    '<div class="info">' + file.name + '</div>' +
                '</div>'
                ),
            $img = $li.find('img');
		
		//把定義的li加入到list中
        $list.append( $li );

        // 建立縮圖,此過程為非同步,需要傳入callBack(function( error, src )),通常在圖片加入佇列後呼叫此方法,以增強互動性
		//callback有兩個引數,當失敗時呼叫error,src存放的是縮圖的地址
        uploader.makeThumb( file, function( error, src ) {
            if ( error ) {
                $img.replaceWith('<span>不能預覽</span>');
                return;
            }

            $img.attr( 'src', src );
        }, thumbnailWidth, thumbnailHeight );
    });

    // 檔案上傳過程中建立進度條實時顯示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
        var $li = $( '#'+file.id ),
            $percent = $li.find('.progress span');

        // 避免重複建立
        if ( !$percent.length ) {
            $percent = $('<p class="progress"><span></span></p>')
                    .appendTo( $li )
                    .find('span');
        }

        $percent.css( 'width', percentage * 100 + '%' );
    });

    // 檔案上傳成功,給item新增成功class, 用樣式標記上傳成功。
    uploader.on( 'uploadSuccess', function( file ) {
        $( '#'+file.id ).addClass('upload-state-done');
    });

    // 檔案上傳失敗,現實上傳出錯。
    uploader.on( 'uploadError', function( file ) {
        var $li = $( '#'+file.id ),
            $error = $li.find('div.error');

        // 避免重複建立
        if ( !$error.length ) {
            $error = $('<div class="error"></div>').appendTo( $li );
        }

        $error.text('上傳失敗');
    });

    // 完成上傳完了,成功或者失敗,先刪除進度條。
    uploader.on( 'uploadComplete', function( file ) {
        $( '#'+file.id ).find('.progress').remove();
    });
});


下面是java的後臺程式碼,用於獲取上傳檔案,並將上傳檔案的真實路徑寫入伺服器

http://blog.csdn.net/zsw2zkl/article/details/7426007

package com.lanyou.support.servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

public class FileUpload extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private static Log logger = LogFactory.getLog(FileUpload.class);

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 型別 1事件上傳檔案 2apk
		String t = req.getParameter("t") == null ? "1" : req.getParameter("t")
				.trim();
		String path = "";
		JSONObject ob = new JSONObject();
		try {
			
			//將請求訊息中的每一個專案封裝成單獨DiskFileItem物件的任務
			//當上傳的檔案專案比較小時儲存在記憶體中,比較大時儲存在磁碟零時資料夾中
			//建立檔案倉庫(工廠)
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
			//對上傳的檔案進行設定
			servletFileUpload.setSizeMax(1024 * 1024 * 2);// 最大2M資料
			servletFileUpload.setFileSizeMax(2 * 1024 * 1024);

			servletFileUpload.setHeaderEncoding("UTF-8");// 解決檔名亂碼的問題
			
			//解析請求正文,獲取上傳檔案,不丟擲異常則寫入真實路徑
			//根據請求獲取檔案列表
			List<FileItem> fileItemsList = servletFileUpload.parseRequest(req);
			//從檔案列表中取出單獨的檔案物件
			for (FileItem item : fileItemsList) {
				//判斷該檔案是否是普通的表單型別,該處是file型別進入判斷
				if (!item.isFormField()) {
					//如果上傳的檔案大於指定的大小則return
					if (item.getSize() > 2 * 1024 * 1024) {
						return;
					}

					// System.out.println("上傳檔案的大小:"+item.getSize());
					// System.out.println("上傳檔案的型別:"+item.getContentType());
					// System.out.println("上傳檔案的名稱:"+item.getName());
					
					
					//上傳檔案的名稱
					String fileName = item.getName();

					String ent = "";
					//內容的型別
					if (item.getContentType().equalsIgnoreCase("image/x-png")
							|| item.getContentType().equalsIgnoreCase(
									"image/png")) {
						ent = ".png";
					} else if (item.getContentType().equalsIgnoreCase(
							"image/gif")) {
						ent = ".gif";
					} else if (item.getContentType().equalsIgnoreCase(
							"image/bmp")) {
						ent = ".bmp";
					} else if (item.getContentType().equalsIgnoreCase(
							"image/pjpeg")
							|| item.getContentType().equalsIgnoreCase(
									"image/jpeg")) {
						ent = ".jpg";
					}
					
					//獲取檔案的是那種格式
					if (fileName.lastIndexOf(".") != -1) {
						ent = fileName.substring(fileName.lastIndexOf("."));
					}
					fileName = "ev_" + System.currentTimeMillis() + ent;
					// 定義檔案路徑,根據你的資料夾結構,可能需要做修改
					if (t.equals("1")) {
						path = "upload/ev/" + fileName;
					} else {
						path = "upload/pk/" + fileName;
					}

					// 儲存檔案到伺服器上
					File file = new File(req.getSession().getServletContext()
							.getRealPath(path));
					if (!file.getParentFile().exists()) {
						file.getParentFile().mkdirs();
					}
					item.write(file);
					// logger.info(path);
					// break;
					ob.accumulate("url", path);
				}
			}

			resp.setContentType("text/html; charset=UTF-8");
			resp.getWriter().write(ob.toString());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 響應客戶端
			// resp.setContentType("text/html; charset=UTF-8");
			// resp.getWriter().write(ob.toString());
		}
	}
}