11、Struts2 的文件上傳和下載

文件上傳

  1. 表單準(zhǔn)備

    • 要想使用 HTML 表單上傳一個或多個文件
    • 須把 HTML 表單的 enctype 屬性設(shè)置為 multipart/form-data
    • 須把 HTML 表單的method 屬性設(shè)置為 post
    • 需添加 <input type=“file”> 字段.
  2. Struts 對文件上傳的支持

    • 在 Struts 應(yīng)用程序里, FileUpload 攔截器和 Jakarta Commons FileUpload 組件可以完成文件的上傳.
    • 步驟:
      1. 在 Jsp 頁面的文件上傳表單里使用 file 標(biāo)簽. 如果需要一次上傳多個文件, 就必須使用多個 file 標(biāo)簽, 但它們的名字必須是相同的
      2. 在 Action 中新添加 3 個和文件上傳相關(guān)的屬性. 這 3 個屬性的名字必須是以下格式
        • 基本的文件的上傳: 直接在 Action 中定義如下 3 個屬性, 并提供對應(yīng)的 getter 和 setter
        • [File Name] : 類型-File -被上傳的文件。例如:data(fileName要求和文件表單項的name一致
        • [File Name]ContentType : 類型-String -上傳文件的文件類型。例如:dataContentType(用來接收文件類型(MIME值)
        • [File Name]FileName : String -上傳文件的文件名。例如:dataFileName (用來接收文件的名字
      3. 如果上傳多個文件, 可以使用 List
        • 若傳遞多個文件, 則上述的 3 個屬性, 可以改為 List 類型! 多個文件域的 name 屬性值需要一致.
  3. 示例代碼

<s:form action="testUpload" enctype="multipart/form-data">
   <s:textfield name="userName[0]" label="用戶-1"></s:textfield>
    <s:file name="photos" label="照片"></s:file>
    <s:textfield name="userName[1]" label="用戶-2"></s:textfield>
    <s:file name="photos" label="照片"></s:file>
    <s:textfield name="userName[2]" label="用戶-3"></s:textfield>
    <s:file name="photos" label="照片"></s:file>
    <s:submit value="提交"></s:submit>
</s:form>
public class UploadAction  extends ActionSupport{

    @Setter@Getter
    private List<File> photos;
    @Setter@Getter
    private List<String> photosContentType;
    @Setter@Getter
    private List<String> photosFileName;
    @Setter@Getter
    private List<String> userName;

    public String testUpload() throws IOException {
        System.out.println("userName: "+userName);
        System.out.println("photos: "+photos);
        System.out.println("photosFileName: "+ photosFileName);
        System.out.println("photosContentType: "+photosContentType);

        // 將文件傳到服務(wù)器根目錄下upload文件下
        // 獲取ServletContext
        ServletContext servletContext = ServletActionContext.getServletContext();
        //獲取真實路徑
        String realPath = servletContext.getRealPath("/upload");
        System.out.println(realPath);
        File uploadFile = new File(realPath);
        //判斷路徑是否存在
        if (!uploadFile.exists()){
            //不存在創(chuàng)建
            uploadFile.mkdir();
        }
        for (int i = 0; i < photos.size(); i++) {
            UUID uuid = UUID.randomUUID();
            FileUtils.copyFile(photos.get(i), new File(realPath + "/" + uuid + photosFileName.get(i)));
        }
        return SUCCESS;
    }
}
  1. 處理幾個小問題?

    1. 文件名重名,一般可以在文件名的前面生成一個UUID作為前綴。
    2. 限制單個文件的大小
    3. 限制文件的類型
    4. 限制總文件的大小
  2. 在Struts2 中提供了 FileUpload 攔截器 可以給我們設(shè)置這些屬性值

    • FileUpload 攔截器有 3 個屬性可以設(shè)置.
      • maximumSize: 上傳單個文件的最大長度(以字節(jié)為單位), 默認(rèn)值為 2 MB
      • allowedTypes: 允許上傳文件的類型, 各類型之間以逗號分隔
      • allowedExtensions: 允許上傳文件擴展名, 各擴展名之間以逗號分隔
      • 可以在 struts.xml 文件中覆蓋這 3 個屬性
    • 注意: 在 org.apache.struts2 下的 default.properties 中有對上傳的文件總的大小的限制. 可以使用常量的方式來修改該限制struts.multipart.maxSize=2097152
<constant name="struts.devMode" value="true"/>

 <!-- 在這修改總文件的的大小 -->
 <constant name="struts.multipart.maxSize" value="2097152"/>
 <package name="default" namespace="/" extends="struts-default">
    <interceptors>
        <interceptor-stack name="myInterceptor">
            <interceptor-ref name="defaultStack">
                <!-- 修改單個文件大小,Commons FileUpload 組件默認(rèn)接受上傳文件總的最大值為 2M -->
                <param name="fileUpload.maximumSize">57,408</param>
                <!-- 允許上傳的文件類型 -->
                <param name="fileUpload.allowedTypes">image/pjpeg,image/gif</param>
                <!-- 允許上傳文件的擴展名 -->
                <param name="fileUpload.allowedExtensions">jpg,gif</param>
            </interceptor-ref>
        </interceptor-stack>
    </interceptors>

    <default-interceptor-ref name="myInterceptor"></default-interceptor-ref>
    
    <action name="testUpload" class="org.pan.action.UploadAction" method="testUpload">
        <result name="success">/WEB-INF/views/success.jsp</result>
        <result name="input">/upload.jsp</result>
    </action>
</package>
  1. 上傳文件相關(guān)的錯誤消息?
    1. 與文件上傳有關(guān)的出錯消息在 struts-messages.properties 文件里預(yù)定義.
    2. 可以在文件上傳 Action 相對應(yīng)的資源文件 或者 在 i18n_zh_CN.properties 國際化資源文件中重新定義錯誤消息
struts.messages.error.file.too.large=你傳的文件太大了
struts.messages.error.content.type.not.allowed=文件類型錯誤
struts.messages.error.file.extension.not.allowed=擴展名錯誤
struts.messages.upload.error.SizeLimitExceededException=文件總大小超過上限

文件下載

  1. 在某些應(yīng)用程序里, 可能需要動態(tài)地把一個文件發(fā)送到用戶的瀏覽器中, 而這個文件的名字和存放位置在編程時是無法預(yù)知的

  2. Stream 結(jié)果類型

    • Struts 專門為文件下載提供了一種 Stream 結(jié)果類型. 在使用一個 Stream 結(jié)果時, 不必準(zhǔn)備一個 JSP 頁面.
    • Stream 結(jié)果類型可以設(shè)置如下參數(shù):
      • contentType:被下載的文件的 MIME 類型。默認(rèn)值為 text/plain
      • contentLength:被下載的文件的大小,以字節(jié)為單位
      • contentDisposition: 可以設(shè)置下載文件名的ContentDispositon 響應(yīng)頭,默認(rèn)值為 inline,通常設(shè)置為如下格式:
        • attachment;filename="document.pdf".
      • inputName:Action 中提供的文件的輸入流。默認(rèn)值為 inputStream
      • bufferSize:文件下載時緩沖區(qū)的大小。默認(rèn)值為 1024
      • allowCaching :文件下載時是否允許使用緩存。默認(rèn)值為 true
      • contentCharSet:文件下載時的字符編碼。
        • 以上參數(shù)可以在 Action 中以 getter 方法的方式提供!
    • Stream 結(jié)果類型的參數(shù)可以在 Action 以屬性的方式覆蓋
    • 具體使用細(xì)節(jié)參看 struts-2.3.15.3-all/struts-2.3.15.3/docs/WW/docs/stream-result.html
  3. 示例代碼

<a href="testDownLoad">下載</a>
public class DownLoadAction extends ActionSupport{
    //通常以下這幾個參數(shù)會在Action 中提供
    @Setter@Getter
    private String contentType;
    @Setter@Getter
    private long contentLength;
    @Setter@Getter
    private String contentDisposition;
    @Setter@Getter
    private InputStream inputStream;

    public String testDownLoad() throws FileNotFoundException, UnsupportedEncodingException {
        //獲取ServletContext
        ServletContext servletContext = ServletActionContext.getServletContext();
        //獲取文件的路徑
        String realPath = servletContext.getRealPath("/WEB-INF/file/至少還有你.mp3");
        //獲取文件的流
        inputStream = new FileInputStream(realPath);
        //設(shè)置文件的類型
        contentType = servletContext.getMimeType(realPath);
        //獲取文件的長度
        contentLength = new File(realPath).length();
        //設(shè)置文件名
        String fileName = "至少還有你.mp3";
        fileName = new String(fileName.getBytes("gbk"),"iso8859-1");
        contentDisposition = "attachment;filename="+fileName;
        return SUCCESS;
    }
}
<!-- 文件下載 -->
<action name="testDownLoad" class="org.pan.action.DownLoadAction" method="testDownLoad">
    <result type="stream">
        <!-- 文件緩沖大小 -->
        <param name="bufferSize">2048</param>
    </result>
</action>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,659評論 19 139
  • 概述 Struts就是基于mvc模式的框架!(struts其實也是servlet封裝,提高開發(fā)效率!) Strut...
    奮斗的老王閱讀 3,185評論 0 51
  • 標(biāo)簽 如果要配置的標(biāo)簽,那么必須要先配置標(biāo)簽,代表的包的概念。 包含的屬性 name包的名稱,要求是唯一的,管理a...
    偷偷得路過閱讀 1,516評論 0 0
  • 之前介紹servlet3.0新特性的時候有提到過servlet API提供了一個part類來實現(xiàn)對文件的上傳和保存...
    Single_YAM閱讀 373評論 2 6
  • 本文包括:1、文件上傳概述2、利用 Commons-fileupload 組件實現(xiàn)文件上傳3、核心API——Dis...
    廖少少閱讀 12,746評論 5 91

友情鏈接更多精彩內(nèi)容