struts2之檔案上傳
struts2對檔案的上傳進行了封裝,主要核心是FileUploadInterceptor攔截器對檔案上傳請求的操作,那麼對於檔案上傳的實現,我們開發或者需要注意哪些呢?
我們先來大概解析一下FileUploadInterceptor攔截器對應的javadoc文件:
Open Declaration org.apache.struts2.interceptor.FileUploadInterceptor /* * FileUploadInterceptor攔截器是基於MultiPartRequestWrapper,將會攔截所有包含檔案的請求 * 以下是所要求引數格式 */ Interceptor that is based off of MultiPartRequestWrapper, which is automatically applied for any request that includes a file. It adds the following parameters, where [File Name] is the name given to the file uploaded by the HTML form: //所要上傳的檔案(自定義名字) [File Name] : File - the actual File //所上傳檔案的內容型別 [File Name]ContentType : String - the content type of the file //所上傳檔案的真實檔名 [File Name]FileName : String - the actual name of the file uploaded (not the HTML name) /* * 可以在Action類中提供setter方法獲取這些檔案 */ You can get access to these files by merely providing setters in your action that correspond to any of the three patterns above, such as setDocument(File document), setDocumentContentType(String contentType), etc. See the example code section. /* * 如果Action類實現了ValidationAware,FileUploadInterceptor攔截器將會加入錯誤訊息,這些訊息是預設的 * 國際化訊息,可以通過以下方式覆蓋 */ This interceptor will add several field errors, assuming that the action implements ValidationAware. These error messages are based on several i18n values stored in struts-messages.properties, a default i18n file processed for all i18n requests. You can override the text of these messages by providing text for the following keys: //通常檔案上傳出錯的訊息 struts.messages.error.uploading - a general error that occurs when the file could not be uploaded //上傳檔案超過最大值 struts.messages.error.file.too.large - occurs when the uploaded file is too large //上傳的檔案內容不合法 struts.messages.error.content.type.not.allowed - occurs when the uploaded file does not match the expected content types specified //上傳檔案的副檔名不合法 struts.messages.error.file.extension.not.allowed - occurs when the uploaded file does not match the expected file extensions specified /* * 通過配置 FileUploadInterceptor 攔截器的引數的方式來進行限制 */ Interceptor parameters: //以位元組為單位,預設的最大值為2M maximumSize (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set on the action. Note, this is not related to the various properties found in struts.properties. Default to approximately 2MB. //允許的上傳檔案的型別. 多個使用 ","分割.如果沒有指定,攔截器將會在Action類中設定檔案參考 allowedTypes (optional) - a comma separated list of content types (ie: text/html) that the interceptor will allow a file reference to be set on the action. If none is specified allow all types to be uploaded. //允許的上傳檔案的副檔名. 多個使用 , 分割. allowedExtensions (optional) - a comma separated list of file extensions (ie: .html) that the interceptor will allow a file reference to be set on the action. If none is specified allow all extensions to be uploaded. /* * 擴充套件攔截器 */ Extending the interceptor: You can extend this interceptor and override the acceptFile method to provide more control over which files are supported and which are not. Example code: //例項程式碼 <action name="doUpload" class="com.example.UploadAction"> <interceptor-ref name="fileUpload"/> <interceptor-ref name="basicStack"/> <result name="success">good_result.jsp</result> </action> /* * 在檔案上傳的表單中必須做如下設定 */ You must set the encoding to multipart/form-data in the form where the user selects the file to upload. <s:form action="doUpload" method="post" enctype="multipart/form-data"> <s:file name="upload" label="File"/> <s:submit/> </s:form>
其實文件中還有Action類的示例,在這裡省去,將在下面的例子中討論。根據上面的檔案描述,用一個例子示範:
Action類:
這裡須注意一點:File對應的引數名可以自定義,但是ContentType和FileName必須在之前加上定義的檔案引數名。如:自定義檔名是[fileFieldName],那麼其他兩個引數必須是:[fileFieldName]ContentType和[fileFieldName]FileName。
jsp頁面:import java.io.File; import com.opensymphony.xwork2.ActionSupport; public class FileUploadAction extends ActionSupport { private static final long serialVersionUID = 1L; private File test; private String testContentType; private String testFileName; public File getTest() { return test; } public void setTest(File test) { this.test = test; } public String getTestContentType() { return testContentType; } public void setTestContentType(String testContentType) { this.testContentType = testContentType; } public String getTestFileName() { return testFileName; } public void setTestFileName(String testFileName) { this.testFileName = testFileName; } @Override public String execute() throws Exception { System.out.println(test); System.out.println(testContentType); System.out.println(testFileName); return super.execute(); } }
國際化檔案globalMessage.properties中配置訊息:<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <!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>Insert title here</title> </head> <body> <!-- 須設定enctype屬性為"multipart/form-data" --> <s:form action="fileUpload" method="post" enctype="multipart/form-data"> <!-- struts2中檔案選擇要用 s:file標籤 --> <s:file name="test" label="file"></s:file> <s:submit></s:submit> </s:form> </body> </html>
struts.messages.error.uploading=\u6587\u4ef6\u4e0a\u4f20\u51fa\u9519\u7684\u6d88\u606f
struts.messages.error.file.too.large=\u6587\u4ef6\u8d85\u8fc7\u6700\u5927\u503c\u7684\u6d88\u606f
struts.messages.error.content.type.not.allowed=\u6587\u4ef6\u5185\u5bb9\u7c7b\u578b\u4e0d\u5408\u6cd5\u7684\u6d88\u606f
struts.messages.error.file.extension.not.allowed=\u6587\u4ef6\u6269\u5c55\u540d\u4e0d\u5408\u6cd5\u7684\u6d88\u606f
在struts.xml配置攔截器棧和action:
在struts.xml檔案中,對package標籤下元素配置必須按照這個順序:result-types、interceptors、default-interceptor-ref、default-action-ref、default-class-ref、global-results、global-exception-mappings、action*,也就是說上面的testStack必須在action之前配置。否則會報錯,並提示:The content of element type "package" must match "(result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)".
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 配置國際化資原始檔-->
<constant name="struts.custom.i18n.resources" value="globalMessage"></constant>
<!-- 設定臨時存放資料夾,用於檔案上傳 -->
<constant name="struts.multipart.saveDir" value="/tmp"></constant>
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<!-- 自定義攔截器棧,即在預設攔截器棧的基礎上新增params -->
<interceptor-stack name="testStack">
<interceptor-ref name="defaultStack">
<!-- 設定上傳檔案的最大值 -->
<param name="fileUpload.maximumSize">2097152</param>
<!-- 規定上傳檔案的內容格式 -->
<param name="fileUpload.allowedTypes">text/html,text/xml</param>
<!-- 規定上傳檔案的字尾名 -->
<param name="fileUpload.allowedExtensions">html,dtd,xml</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="fileUpload" class="com.fileupload.action.FileUploadAction">
<result name="success">/success.jsp</result>
<result name="input">/upload.jsp</result>
<!-- 在action中引入自定義攔截器 -->
<interceptor-ref name="testStack"></interceptor-ref>
</action>
</package>
</struts>
執行結果,當上傳的檔案與攔截器中配置的引數不符的時候:
在struts2中可以同時上傳多個檔案,在上述Action類中,將三個引數改為List型別的即可。