文件上傳是WEB應用常常須要面對的問題。在大部分時候,用戶的請求參數是在表單域輸入的字符串,但若是爲表單元素設置enctype=「multipart/form-data」屬性,則提交表單時候再也不是以字符串方式提交請求參數,而是以二進制編碼的方式提交請求,此時直接經過HttpServletRequest的getParameter方法就沒法正常獲取請求參數的值,而經過二進制流來獲取請求內容,就能夠獲取到上傳文件的內容,從而實現文件上傳的功能。html
Struts2的文件上傳支持在原有的文件上傳項目上作了進一步的封裝,只須要將屬性封裝表單的文件域,就可很是輕鬆地完成文件上傳。前端
1、首先講解一下,在頁面中標籤form表單中的屬性:java
1)action屬性指定了表中提交的URL;web
2)method屬性指定是以POST方式仍是GET方式提交請求;apache
3) Enctype屬性指的是表單數據的編碼方式,該屬性有以下3個值:服務器
application/x-www-form-urlencoded:默認編碼方式,它只處理表單 裏的value屬性值。app
multipart/form-data:指的是以二進制流的凡是來處理表單數據,這 種方式會把文件或者文件的內容也封裝到請求參數裏。jsp
text/plain:當表單的action屬性爲mailto:url的形式時比較方便, 這種方式主要適用於直接經過表單發送郵件的方式。工具
2、使用Struts2完成文件上傳post
1.前端頁面必須知足條件
1) 必須同步提交 form 表單
2) Form 表單編碼方式 multipart/form-data
3) 提交方式必須爲 post
4) 上傳文件對應 標籤input type=」file」 元素要提供 name 屬性
演示代碼:
<%@ 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>Struts完成文件上傳</title> </head> <body> <!-- 爲了完成文件上傳: 1)標籤form表單設置enctype=「multipart/form-data」屬性; 2)表單爲同步提交方式 method="post"; 3)上傳文件對應 標籤input type=」file」 元素要提供 name 屬性 --> <form action="${pageContext.request.contextPath}/fileUpload" enctype="multipart/form-data" method="post"> 文件標題:<input type="text" name="title" /><br /> 選擇文件:<input type="file" name="uploadObj" /><br /> <input type="submit" value="上傳" /> </form> </body> </html>
2.服務器端Action注意事項
1)提供文件上傳的三個屬性
private File xxx 該屬性封裝了該文件域對應的文件內容;
private xxxFileName 該屬性封裝了該文件與對應的文件的文件名;
private xxxContentType 該屬性封裝了該文件與對應的文件的文件類型;
UploadAction中代碼演示:
package cn.struts2.action.upload; import java.io.File; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; //繼承ActionSupport爲了接受頁面其餘參數; public class FileUploadAction extends ActionSupport { private File uploadObj; // 上傳文件對象 private String uploadObjFileName; // 上傳文件名稱 private String uploadObjContentType;// 上傳文件類型 private String title; // 頁面表單中參數 public File getUploadObj() { return uploadObj; } public void setUploadObj(File uploadObj) { this.uploadObj = uploadObj; } public String getUploadObjFileName() { return uploadObjFileName; } public void setUploadObjFileName(String uploadObjFileName) { this.uploadObjFileName = uploadObjFileName; } public String getUploadObjContentType() { return uploadObjContentType; } public void setUploadObjContentType(String uploadObjContentType) { this.uploadObjContentType = uploadObjContentType; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } // 完成文件上傳的方法 public String uploadFile() { try { // 獲取服務器端upload文件夾目錄的絕對磁盤路徑 String path = ServletActionContext.getServletContext().getRealPath("/upload"); // 建立一個服務文件 File file = new File(path,uploadObjFileName); //使用struts2的封裝的工具FileUtils,完成文件上傳 FileUtils.copyFile(uploadObj, file); //傳遞文件對象和目標路徑 //將文件標題和上傳文件路徑存入值棧 ValueStack vs = ActionContext.getContext().getValueStack(); vs.set("title", title); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("上傳文件失敗"); } return SUCCESS; } }
3.在配置Struts.xml文件上傳的Action與配置普通Action並無太大的區別,同樣是指定該Action的name,以及該Action的實現類。
固然,還應該爲該Action配置<result .../>元素。
代碼演示:
<!-- 配置頁面請求路徑和訪問到Action中的方法 --> <package name="default" namespace="/" extends="struts-default"> <action name="fileUpload" class="cn.struts2.action.upload.FileUploadAction" method="uploadFile"> <result name="success" >/success.jsp</result> </action>
4.最後web.xml文件的配置:
1)定義struts2的核心filter
2)定義Struts2核心Filter攔截的URL
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>struts_demo</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <!-- 定義struts2的核心filter --> <filter-name>struts2Filter</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <!-- 定義Struts2核心Filter攔截的URL--> <filter-mapping> <filter-name>struts2Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
5.完成這些配置後,若是咱們在頁面點擊選擇文件,並遊覽到須要上傳的文件,而後單擊「上傳」按鈕,該上傳請求將被UploadAction處理,處理結束後轉入success.jsp頁面,該頁面使用了簡單的Struts2標籤來顯示文件上傳。
success.jsp頁面的代碼以下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s"%> <!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> <h2>上傳文件成功!</h2> <!-- 輸出表單中上傳文件的標題屬性的名稱和文件內容 --> 文件標題:<s:property value="title" ></s:property><br> 文件:<img src="<s:property value='file'></s:property>" style="width: 200px;height: 200px"> </body> </html>
經過以上案例,文件大小限制、文件類型處理等問題,咱們如何來解決呢?
1)實現文件過濾
在action中設置攔截器;並其設置屬性的值,實現相關的功能(能夠攔截上傳指定類型的文件--不然給用戶跳轉到提示頁面)
或者在配置文件聲明常量:
<constant name=」struts.multipart.maxSize」 value=」209715200」></contant>
註釋說明:
若是在struts.xml文件中,導入自定義的攔截器,那麼同時也要將默認的攔截器defaultStack導入。
若是在單數設置某個action的上傳文件大小,超過了系統默認大小是不起做用的。