首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Struts 2 文件上傳下載完整實戰(二):多文件上傳、類型限制、國際化錯誤與 Stream 下載

     編輯:Java 相關知識

前言

承接上篇,本文深入 Struts 2 文件上傳進階特性:多文件上傳、文件類型/大小限制、錯誤信息國際化,以及基於 stream Result Type 的文件下載實現。

文件上傳三要素(回顧)

  1. Form method="post"
  2. Form enctype="multipart/form-data"
  3. <input type="file"> 欄位

Struts 2 文件上傳核心規約

Action 中需聲明三組屬性(名稱固定模式):

屬性類型說明
myFileFile / File[] / List<File>上傳文件內容(臨時文件)
myFileFileNameString / String[] / List<String>原始文件名
myFileContentTypeString / String[] / List<String>MIME 類型

規則:屬性名 對應表單 name,後綴固定為 FileName、ContentType。

單文件上傳完整示例

1. JSP 頁面

<%@ taglib prefix="s" uri="/struts-tags" %>
<s:actionerror/> <s:fielderror/>
<form action="upload1.action" method="post" enctype="multipart/form-data">
    用戶名:<input type="text" name="username"/><br/>
    靓照:<input type="file" name="photo"/><br/>
    <input type="submit" value="上傳"/>
</form>

2. Action 類

package com.itheima.actions;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class UploadAction1 extends ActionSupport {
    private String username;
    private File photo;
    private String photoFileName;
    private String photoContentType;
    // getter/setter 省略

    public String upload() {
        System.out.println(photoFileName + ":" + photoContentType);
        System.out.println(username);

        String realPath = ServletActionContext.getServletContext().getRealPath("/images");
        File dir = new File(realPath);
        if (!dir.exists()) dir.mkdirs();

        try {
            FileUtils.copyFile(photo, new File(dir, photoFileName));
            return SUCCESS;
        } catch (IOException e) {
            e.printStackTrace();
            return ERROR;
        }
    }
}

3. struts.xml 配置(含類型/大小限制)

<action name="upload1" class="com.itheima.actions.UploadAction1" method="upload">
    <interceptor-ref name="defaultStack">
        <param name="fileUpload.allowedTypes">image/jpeg,image/png</param>
        <param name="fileUpload.allowedExtensions">jpg,jpeg,png</param>
        <param name="fileUpload.maximumSize">2097152</param> <!-- 2MB -->
    </interceptor-ref>
    <result>/success.jsp</result>
    <result name="error">/error.jsp</result>
    <result name="input">/index.jsp</result> <!-- 驗證失敗返回 -->
</action>

fileUpload 攔截器三大參數

  • maximumSize:最大字節數,默認 2MB
  • allowedTypes:允許 MIME 類型,逗號分隔
  • allowedExtensions:允許擴展名,逗號分隔

超限或類型不匹配會觸發 input 結果,可通過 <s:actionerror/>、<s:fielderror/> 顯示錯誤。

錯誤信息國際化(中文化)

1. 創建資源文件 fileuploadmessage.properties

struts.messages.error.uploading=上傳錯誤: {0}
struts.messages.error.file.too.large=上傳文件太大: {0} "{1}" "{2}" {3}
struts.messages.error.content.type.not.allowed=上傳文件類型不允許: {0} "{1}" "{2}" {3}
struts.messages.error.file.extension.not.allowed=上傳文件後綴不允許: {0} "{1}" "{2}" {3}

2. struts.xml 載入

<constant name="struts.custom.i18n.resources" value="cn.xxx.fileuploadmessage"/>

佔位符含義:{0}=表單字段名,{1}=原始文件名,{2}=臨時文件名,{3}=文件類型/大小。

多文件上傳

Action 屬性改為數組或 List:

private File[] photo;
private String[] photoFileName;
private String[] photoContentType;

public String upload() {
    // 遍歷數組逐個保存
    for (int i = 0; i < photo.length; i++) {
        FileUtils.copyFile(photo[i], new File(dir, photoFileName[i]));
    }
    return SUCCESS;
}

JSP 中放置多個 <input type="file" name="photo"> 即可。

文件下載:Stream Result Type 詳解

1. 原理

  • 指定 type="stream" 結果類型
  • Action 提供 InputStream 類型屬性(如 image)
  • 通過參數指定 contentType、contentDisposition、contentLength

2. Action 實現

package com.itheima.actions;
import java.io.*;
import org.apache.commons.io.FilenameUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class DownloadAction extends ActionSupport {
    private InputStream image;
    private String filename;
    private long filesize;
    // getter 省略

    public String download() throws Exception {
        String fileRealPath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/classes/霉女.jpg");
        filename = FilenameUtils.getName(fileRealPath);
        filesize = new File(fileRealPath).length();
        image = new FileInputStream(fileRealPath);
        return SUCCESS;
    }
}

3. struts.xml 配置(重點:中文文件名編碼)

<action name="download" class="com.itheima.actions.DownloadAction" method="download">
    <result type="stream">
        <param name="inputName">image</param>
        <param name="contentType">application/octet-stream</param>
        <!-- OGNL 表達式調用 URLEncoder 靜態方法,需開啟 struts.ognl.allowStaticMethodAccess -->
        <param name="contentDisposition">attachment;filename=${@java.net.URLEncoder@encode(filename,'UTF-8')}</param>
        <param name="contentLength">${filesize}</param>
    </result>
</action>

<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>

4. 關鍵點總結

  • inputName 對應 Action 中 InputStream 屬性名
  • contentDisposition: attachment 強制下載而非瀏覽器打開
  • 中文文件名必須 URLEncoder.encode,配合 OGNL 靜態調用
  • contentLength 讓瀏覽器顯示進度條
  • 大文件建議使用 BufferedInputStream 分塊讀取,避免 OOM

總結

Struts 2 文件上傳下載核心在於:約定屬性命名 → fileUpload 攔截器參數化配置 → 國際化友好提示 → Stream Result 流式輸出。掌握多文件數組綁定、類型大小限制、中文文件名編碼三大難點,即可應對企業級文件交互場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved