一、使用 commons-fileupload.jar 實現文件上傳
1.1 commons-fileupload.jar 簡介
Commons FileUpload 是 Apache Commons 下的一個子項目,commons-fileupload 包能夠讓你的 servlet 和 web 應用能夠很方便的實現健壯的、高性能的文件上傳功能。
FileUpload 可以解析 HTTP 請求。如果一個 HTTP 請求使用 POST 方式提交,且該請求的內容類型標識爲 “multipart/form-data” ,那麼 FileUpload 就可以解析這個請求,並且使得到的結果更容易被程序所使用。
發送 “multipart/form-data” 請求的最簡單的方法是通過頁面表單提交請求。
<!-- 注:頁面文件上傳表單, method 屬性必須爲 "post",且編碼類型 enctype 屬性必須是 "multipart/form-data",任何語言都需要滿足這兩點。-->
<form action="fileUpload.action" method="post" enctype="multipart/form-data">
file: <input type="file" name="file"> <br>
username: <input type="text" name="username"><br>
<input type="submit" value="sumit">
</form>
1.2 在 servlet 類中使用Commons-fileupload 實現簡單的文件上傳
public class UploadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
String path = req.getRealPath("/fileUp");
//指定大文件的臨時存放目錄
factory.setRepository(new File(path));
//設置大文件的最小大小,默認爲10K,設置單位爲字節,現在設置的大小爲1G
factory.setSizeThreshold(1024*1024);
ServletFileUpload upload = new ServletFileUpload(factory);
try{
//list 集合裏不但存放了上傳的文件信息,還存放表單的其他類型請求的信息
List<FileItem> list = upload.parseRequest(req);
for(FileItem item:list){
String name = item.getFieldName();
//判斷是否爲普通的表單內容
if(item.isFormField()){
String value = item.getString();
System.out.println(name+"="+value);
req.setAttribute(name, value);
}else{
//獲取文件名,有些瀏覽器會包括路徑,如opera瀏覽器
String value = item.getName();
//如果忽略opera瀏覽器則不需要刪除路徑的操作
int start = value.lastIndexOf("\\");
String fileName = value.substring(start+1);
req.setAttribute(name, fileName);
//item.write完成上傳文件寫入服務器指定目錄的工作,且會自動刪除臨時文件
// item.write(new File(path,fileName));
//如果需要自己實現寫入硬盤的操作,需要刪除臨時文件
OutputStream os = new FileOutputStream(new File(path,fileName));
InputStream is = item.getInputStream();
byte[] buffer = new byte[400];
int length = 0;
while((length = is.read(buffer))!= -1){
os.write(buffer, 0,length);
}
is.close();
os.close();
}
}
}catch(Exception e){
e.printStackTrace();
}
//將請求轉發給fileUploadResult.jsp結果頁面
req.getRequestDispatcher("/fileUp/fileUploadResult.jsp").forward(req, resp);;
}
}
二 使用 struts2 實現文件上傳功能
struts2 沒有自己的文件上傳實現,它僅僅是封裝了common-fileupload 等第三方的文件上傳的工具。
struts2 中在 default.properties 文件中設置了默認的最大上傳文件大小爲2M:
struts.multipart.maxSize=2097152(單位:byte,字節)
可在程序中創建struts.properties,或者在 struts.xml 中重新制定該屬性的大小:
#在struts.properties中設置最大文件上傳大小爲1G
struts.multipart.maxSize=1073741824
<!-- 在struts.xml中設置最大文件上傳大小爲1G -->
<constant name="struts.multipart.maxSize" value="1073741824"></constant>
struts2 實現文件上傳功能的示例:
public class UploadAction extends ActionSupport {
private String username;
//struts2會自動將上傳的文件轉換爲File對象,使用file.getName()會獲得臨時文件的文件名
private File file;
//獲得上傳文件的文件名,不能用file.getName獲得。
//且其命名規則中file爲上傳文件的表單的name屬性值,加"FileName";
private String fileFileName;
//獲得上傳文件的類型
//命名規則:上傳文件的表單的name屬性值,加"FileName"
private String fileContentType;
//對於多文件上傳可設置List類型屬性或多個滿足命名規則的不同屬性:
//private List<File> file;
//private List<String> fileFileName;
//private List<String> fileContentType;
@Override
public String execute() throws Exception {
String root = ServletActionContext.getRequest().getRealPath("/fileUp");
System.out.println(root);
InputStream is = new FileInputStream(file);
System.out.println("fileFileName: "+fileFileName);
File destFile = new File(root,fileFileName);
OutputStream os = new FileOutputStream(destFile);
byte[] buffer = new byte[400];
int length = 0;
while(-1 != (length = is.read(buffer))){
os.write(buffer,0,length);
}
is.close();
os.close();
return SUCCESS;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
public String getFileContentType() {
return fileContentType;
}
public void setFileContentType(String fileContentType) {
this.fileContentType = fileContentType;
}
}
三、struts2 實現下載功能
struts2 實現下載實例一:
// DownloadAction.java
public class DownloadAction extends ActionSupport {
// 用於動態生成下載的文件名
private String filename;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
//主要的執行方法
public InputStream getDownloadFile(){
//如果輸入的是中文名文件,不做處理在頁面上顯示會出現亂碼的情況
//需要做如下處理:this.filename = new String("中文.txt".getBytes("gbk"),"8859_1");gbk爲操作系統默認編碼,8859_1是http協議要求編碼
//參考資料:http://jiapumin.iteye.com/blog/1006144
this.filename = "haha.txt";
return ServletActionContext.getServletContext().getResourceAsStream("/download/xxx.txt");
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
<!-- struts.xml -->
<package name="struts2" extends="struts-default" namespace="/">
<action name="downloadFile" class="com.struts2.download.DownloadAction">
<!-- "contentDisposition" 屬性爲http協議的一個屬性
"attachment;"不加的話默認爲 inline ,當下載的文件,瀏覽器判定可以打開時會自動打開,不會跳出下載框
filename="xxx" 的值會決定瀏覽器下載時文件的文件名
filename=${filename} 動態生成下載文件顯示的文件名
inputName的值會使程序執行action中的get+屬性值的方法,示例中即爲 getDownloadFile 方法。
-->
<result type="stream">
<param name="contentDisposition">attachment;filename=${filename}</param>
<param name="inputName">downloadFile</param>
</result>
</action>
</package>