JavaEE拾遺01--非同步上傳檔案
阿新 • • 發佈:2018-11-19
今天學習了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的目錄放檔案