1. 程式人生 > >JavaEE拾遺01--非同步上傳檔案

JavaEE拾遺01--非同步上傳檔案

今天學習了JavaEE的Servlet的非同步呼叫和檔案上傳,合著做了一個非同步上傳檔案練習,注意到Servlet是多執行緒的,所以實際操作中不需要非同步操作(我是這麼覺得的),閒話少說,看程式碼

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8"> <title>檔案上傳</title> </head> <body> <form method="post" action="../upload" enctype="multipart/form-data"> 檔名:<input type="text" id="name" name="name" /><br /> 選擇上傳檔案:<input
type="file" id="file" name="file" />
<input type="submit" value="上傳" /> </form> </body> </html>

上面寫了一個jsp頁面,這個頁面的<input type="file" /><form method="post" action="../upload" enctype="multipart/form-data">是可以實現檔案上傳的祕密

接下來是處理檔案上傳的servlet

package liujie.jee.uploadfile;

import
java.io.IOException; import java.io.PrintWriter; import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import liujie.jee.bean.UploadFileExecutor; //使用註解表示這個servlet支援非同步操作, @WebServlet(urlPatterns = { "/upload" }, name = "upload", asyncSupported = true) // 處理檔案上傳的servlet需要使用MultipartConfig標識 @MultipartConfig public class UploadFileServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); // 得到檔名 String fileName = request.getParameter("name"); out.println("開始上傳檔案:" + fileName + ".</br>"); // 示例化非同步呼叫 AsyncContext asct = request.startAsync(); // 設定任務超時時間為10分鐘 asct.setTimeout(10 * 60 * 1000); // 設定非同步呼叫的監聽器,當呼叫完成時提示 asct.addListener(new AsyncListener() { // 出錯時呼叫 @Override public void onError(AsyncEvent event) { } // 完成時呼叫 @Override public void onComplete(AsyncEvent event) { out.println("檔案:" + fileName + "上傳完畢"); } // 開始時呼叫 @Override public void onStartAsync(AsyncEvent event) { } // 超時時呼叫 @Override public void onTimeout(AsyncEvent event) { } }); asct.start(new UploadFileExecutor(asct)); /* * out.println("檔案大小為:" + fileSize + "</br>"); out.println("上傳檔案的型別是:" + * part.getContentType() + ".</br>"); out.println("檔名為:" + filename + * "</br>"); */ } }

註釋比較詳細,就不仔細介紹了

裡面的非同步任務實際上是啟動了一個runnable物件,接下來是這個類的內容

package liujie.jee.bean;

import java.io.IOException;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

public class UploadFileExecutor implements Runnable {
    private AsyncContext asct;
    private Part part;
    private final static String UPLODA_DIR = "z_uploadfiles";

    public UploadFileExecutor(AsyncContext asct) {
        this.asct = asct;
    }

    @Override
    public void run() {
        HttpServletRequest request = (HttpServletRequest) asct.getRequest();
        String fileName = request.getParameter("name");
        try {
            // 獲取上傳的物件
            Part part = request.getPart("file");
            // 獲取儲存的路徑並將檔案吸入改路徑
            part.write(request.getServletContext().getRealPath(UPLODA_DIR)
                    + "\\" + fileName);
            // 完成呼叫
            asct.complete();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ServletException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

注意要在應用根目錄下面建立一個z_uploadfiles的目錄放檔案