HTML5+J2EE實現檔案非同步上傳

來源:互聯網
上載者:User

標籤:

P.S. HTML5經過了W3C的8年努力,終於正式推廣了。這次升級最大的就是升級了XMLHTTPRequest,讓它變成了XMLHTTPRequest Level II(這有啥奇怪的?)。這個對象現在非常強大,可能會讓所有使用jQuery的人全部重新拾起HTML原生的ajax技術。

閑話扯到這,接著是主題:我們今天要實現的就是下面的效果:

這裡面檔案名稱、檔案大小和MIME都是在選擇檔案時讀取和現實,然後點擊上傳之後,上傳進度即時顯示,最後彈出右邊的對話方塊確認檔案資訊(當然這裡我為了方便直接把檔案資訊壓到POST請求裡面了,否則可能亂碼,你也可以試試伺服器端直接讀取)。

接著,看到了這個強大的效果,我們簡單地分析以下思路。

1、我們首先確定實現方式:Javascript將會顯示在用戶端顯示進度(用的是XMLHTTPRequest Level II的幾個新的Event),然後同時上傳檔案資訊和檔案本身,當然是非同步。

2、伺服器端用一個servlet就行,這裡使用commonfileupload接受上傳。

然後看一下新的XMLHTTPRequest Level II,看看如何監視這一過程。

<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>

選擇檔案這裡看到了一個onchange事件,這不是一個新事件,但在HTML5標準中被重新定義了,被用於檔案被選擇的時候調用。

function fileSelected() { //檔案選擇更改時調用的事件    var file = document.getElementById(‘fileToUpload‘).files[0]; //獲得檔案上傳資訊    if (file) { //如果使用者選擇了檔案(沒有選擇的話,file就是null或是undefined,這樣可以判斷)        var fileSize = 0; //檔案大小        if (file.size > 1024 * 1024) //如果檔案大小大於1MB            fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100)                    .toString()                    + ‘MB‘; //轉換檔大小並以MB單位顯示        else            //否則                        fileSize = (Math.round(file.size * 100 / 1024) / 100).toString()                    + ‘KB‘; //否則用KB單位顯示        document.getElementById(‘fileName‘).innerHTML = ‘ ‘ + file.name; //顯示檔案名稱資訊        document.getElementById(‘fileSize‘).innerHTML = ‘ ‘ + fileSize; //顯示檔案大小資訊        document.getElementById(‘fileType‘).innerHTML = ‘ ‘ + file.type; //顯示檔案MIME資訊    }}

這個注釋不是我加的,我也不清楚是誰加的……但是大家應該能看懂了。

function uploadFile() { //點擊上傳按鈕時的時間    var fd = new FormData(); //FormData是Html5的新增類    fd.append("file", document.getElementById(‘fileToUpload‘).files[0]); //向表單資料添加檔案主體    var file = document.getElementById(‘fileToUpload‘).files[0]; //獲得檔案主體    var xhr = new XMLHttpRequest(); //初始化ajax請求    xhr.upload.addEventListener("progress", uploadProgress, false); //HTML5的新的事件,上傳進度改變時,只能在有檔案上傳的情況下調用    xhr.addEventListener("load", uploadComplete, false); //老事件,上傳完成後    xhr.addEventListener("error", uploadFailed, false); //出錯時    xhr.addEventListener("abort", uploadCanceled, false); //中斷時    var caption=document.getElementById("caption").value; //標題(和檔案上傳無關緊要)    fd.append("filename", file.name); //檔案名稱添加到表單資料    fd.append("filesize", file.size); //檔案尺寸添加到表單資料    fd.append("filetype", file.type); //MIME添加到表單資料    fd.append("caption", caption); //標題添加到表單資料    xhr.open("POST", "FileUpload",true); //準備上傳    //xhr.setRequestHeader("Content-Type", "multipart/form-data"); //這句千萬不能有!!!我也不知道為什麼……    xhr.send(fd); //發出請求}

點擊上傳按鈕之後就是這段代碼,FormData也是新加的對象,用於儲存表單資料(某人加的注視應該夠明白了……)。

接著我們看後台,後台使用commonfileupload接收(貌似說過了……),先把代碼貼出來:

package Upload;import java.io.File;import java.io.IOException;import java.io.PrintWriter;import java.util.Iterator;import java.util.List;import javax.servlet.ServletContext;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.FileItemFactory;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import Log.LogManager;public class FileUpload extends HttpServlet {    /**     * Constructor of the object.     */    public FileUpload() {        super();    }    /**     * Destruction of the servlet. <br>     */    public void destroy() {        super.destroy(); // Just puts "destroy" string in log        // Put your code here    }    /**     * The doPost method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to post.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        try {            request.setCharacterEncoding("UTF-8");            DiskFileItemFactory fif=new DiskFileItemFactory();            fif.setSizeThreshold(1024*1024);            ServletFileUpload sfu=new ServletFileUpload(fif);            sfu.setSizeMax(1024*1024*1024);            List items=null;            try {                items=sfu.parseRequest(request);            } catch (FileUploadException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Iterator iter=items.iterator();            String filename="";            String filesize="";            String filetype="";            String caption="";            FileItem fi=null;            while (iter.hasNext()) {                FileItem item = (FileItem) iter.next();                if (item.isFormField()) {                    String name=item.getFieldName();                    if(name.equals("filename")==true){                        filename=item.getString("UTF-8");                    }else if(name.equals("filesize")==true){                        filesize=item.getString("UTF-8");                    }else if(name.equals("filetype")==true){                        filetype=item.getString("UTF-8");                    }else if(name.equals("caption")==true){                        caption=item.getString("UTF-8");                    }                } else {                    fi=item;                }            }            ServletContext application=getServletContext();            String path=(String) application.getAttribute("datapath")+"uploadpath"+application.getAttribute("systempi")+filename;            File f1=new File(path);            try {                fi.write(f1);            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            response.setContentType("text/html; charset=UTF-8");            PrintWriter out = response.getWriter();            out.println("你上傳了一個檔案到伺服器,下面將核實這些資訊:");            out.println("1、檔案名稱:"+filename);            out.println("2、檔案大小:"+filesize);            out.println("3、檔案MIME類型:"+filetype);            out.println("如果資訊全部正確,說明檔案成功上傳了!");            String sqls1="";            LogManager.log("一個檔案上傳請求已經被受理!檔案儲存體於:"+path);            out.flush();            out.close();        } catch (Exception e) {            LogManager.err(e.toString());        }    }    /**     * Initialization of the servlet. <br>     *     * @throws ServletException if an error occurs     */    public void init() throws ServletException {        // Put your code here    }}

還挺簡單的,對嗎?處理HTML5的上傳請求和處理以前版本的上傳請求基本一樣,唯一需要注意的是:原來是你來拼接請求,所以說,位置由你決定,現在FormData拼接請求的字串中項目的順序和append的順序有關,所以別搞錯了(貌似我就搞錯了,先添加了檔案,然後在後台補救了一下……)。

基本上就這些代碼,然後就是添加檔案資訊到資料庫什麼的,具體上傳步驟查查commonfileupload的api好了。

整個項目不方便讓大家下載,但這是一個OJ項目裡面的,有興趣的關注一下進入項目的git。另外如果轉載的話,註明一下,謝謝!

HTML5+J2EE實現檔案非同步上傳

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.