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

Struts 2 文件上傳完整實現指南

     編輯:Java 程式設計入門

核心機制

Struts 2 基於 Commons FileUpload 實現文件上傳:

  1. 請求到達,FileUpload 拦截器解析 multipart/form-data
  2. 文件先存入臨時目錄(默認系統臨時目錄)
  3. 自動綁定到 Action 的屬性(File、String fileName、String contentType)
  4. Action 執行業務邏輯後,臨時文件自動刪除

依賴配置


<dependencies>
    <!-- Struts 2 核心 -->
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <version>2.0.6</version>
    </dependency>
    
    <!-- 文件上傳必需 -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
</dependencies>

前端頁面


<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Struts 2 文件上傳</title></head>
<body>
    <s:form action="fileUpload" method="POST" enctype="multipart/form-data">
        <s:file name="myFile" label="圖片文件" />
        <s:textfield name="caption" label="描述" />
        <s:submit value="上傳" />
    </s:form>
</body>
</html>

關鍵點:enctype="multipart/form-data"、<s:file> 標簽綁定 name="myFile"

Action 類實現


package tutorial;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import java.io.*;

public class FileUploadAction extends ActionSupport {
    
    // 必須的三個屬性(命名約定:字段名、字段名FileName、字段名ContentType)
    private File myFile;
    private String myFileFileName;
    private String myFileContentType;
    
    private String caption;  // 額外表單字段
    
    // 業務屬性
    private String savePath = "/uploads";  // 相對路徑
    private long maxSize = 10 * 1024 * 1024;  // 10MB
    private String[] allowedTypes = {"image/jpeg", "image/png", "image/gif"};

    @Override
    public String execute() throws Exception {
        // 1. 校驗文件存在
        if (myFile == null) {
            addFieldError("myFile", "請選擇文件");
            return INPUT;
        }
        
        // 2. 校驗文件大小
        if (myFile.length() > maxSize) {
            addFieldError("myFile", "文件過大,最大 " + maxSize/1024/1024 + "MB");
            return INPUT;
        }
        
        // 3. 校驗文件類型
        boolean allowed = false;
        for (String type : allowedTypes) {
            if (type.equals(myFileContentType)) {
                allowed = true;
                break;
            }
        }
        if (!allowed) {
            addFieldError("myFile", "不支持的文件類型");
            return INPUT;
        }
        
        // 4. 生成唯一文件名防衝突
        String ext = myFileFileName.substring(myFileFileName.lastIndexOf("."));
        String newFileName = System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8) + ext;
        
        // 5. 確保保存目錄存在
        String realPath = ServletActionContext.getServletContext().getRealPath(savePath);
        File destDir = new File(realPath);
        if (!destDir.exists()) destDir.mkdirs();
        
        // 6. 保存文件(使用流複製,避免內存溢出)
        File destFile = new File(destDir, newFileName);
        try (InputStream is = new FileInputStream(myFile);
             OutputStream os = new FileOutputStream(destFile)) {
            byte[] buffer = new byte[8192];
            int len;
            while ((len = is.read(buffer)) > 0) {
                os.write(buffer, 0, len);
            }
        }
        
        // 7. 記錄業務信息(可存入數據庫)
        System.out.println("上傳成功: " + newFileName + ", 描述: " + caption);
        
        return SUCCESS;
    }

    // Getter/Setter 省略...
}

Struts 配置


<package name="default" extends="struts-default">
    <action name="fileUpload" class="tutorial.FileUploadAction">
        <interceptor-ref name="defaultStack">
            <param name="fileUpload.maximumSize">10485760</param>  <!-- 10MB -->
            <param name="fileUpload.allowedTypes">image/jpeg,image/png,image/gif</param>
        </interceptor-ref>
        
        <result name="success">/upload_success.jsp</result>
        <result name="input">/FileUpload.jsp</result>
    </action>
</package>

關鍵配置參數

參數說明默認值
maximumSize最大文件大小(字節)2MB
allowedTypes允許的 MIME 類型,逗號分隔無限制
allowedExtensions允許的擴展名,逗號分隔無限制

進階最佳實踐

1. 多文件上傳


// JSP
<s:file name="files" label="文件1" />
<s:file name="files" label="文件2" />

// Action
private List<File> files;
private List<String> filesFileName;
private List<String> filesContentType;

2. 大文件流式處理(避免臨時文件)


// 自定義 Interceptor 繼承 FileUploadInterceptor
// 重寫 saveFile() 直接流式寫入目標位置

3. 上傳進度條

  • 需配合 AJAX 輪詢或 WebSocket
  • Struts 2.5+ 支持 FileUploadInterceptor 進度監聽

4. 安全加固

  • 驗證文件魔數(而非僅靠擴展名/MIME)
  • 上傳目錄配置為不可執行
  • 文件名去路徑遍歷字符(../)
  • 病毒掃描集成

常見問題排查

現象原因解決
myFile 為 null表單缺少 enctype 或 name 不匹配檢查 enctype="multipart/form-data"、name 一致性
上傳大文件失敗超過 maximumSize 或請求超時調大 maximumSize、增加請求超時時間
中文文件名亂碼編碼不一致確保 JSP、Action、Server 統一 UTF-8
臨時文件未刪除異常中斷或配置錯誤配置定時清理任務、使用 try-with-resources

Struts 2 文件上傳通過攔截器實現聲明式綁定,掌握三屬性約定、校驗邏輯、安全配置,即可構建健壯的上傳功能。

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