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

Struts2 實現文件下載功能(含中文檔名編碼處理)

     編輯:Java 相關知識

核心思路

Struts2 通過 Result Type = "stream" 實現文件下載,關鍵在於:

  1. Action 提供 InputStream getInputStream() 返回文件流。
  2. Action 提供 String getDownloadFileName() 返回經編碼的文件名,解決中文亂碼。
  3. struts.xml 中配置 contentDisposition 為 attachment;filename="${downloadFileName}"。

Action 類完整實現

package com.example.action;

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

import javax.servlet.ServletContext;
import java.io.*;

public class DownloadAction extends ActionSupport {
    private static final long serialVersionUID = 1L;

    // 前端傳入的相對路徑(如 /upload/xxx.pdf)
    private String inputPath;
    // 前端傳入的文件名(含中文)
    private String fileName;

    public String downloadFile() throws Exception {
        ServletContext context = ServletActionContext.getServletContext();
        String baseDir = context.getRealPath("/upload");
        String targetFile = context.getRealPath(inputPath);

        // 安全校驗:防止目錄遍歷攻擊
        if (!targetFile.startsWith(baseDir)) {
            return null; // 或拋出異常
        }
        return SUCCESS; // 對應 struts.xml 中 name="success"
    }

    // 供 Stream Result 讀取的輸入流
    public InputStream getInputStream() throws UnsupportedEncodingException {
        // 關鍵:ISO-8859-1 → UTF-8 轉碼,修正中文路徑
        String decodedName = new String(fileName.getBytes("ISO-8859-1"), "UTF-8");
        String fullPath = inputPath + File.separator + decodedName;
        return ServletActionContext.getServletContext().getResourceAsStream(fullPath);
    }

    // 供 Content-Disposition 使用的下載文件名
    public String getDownloadFileName() throws UnsupportedEncodingException {
        // 瀏覽器兼容性編碼:這裡採用 ISO-8859-1,亦可根據 User-Agent 做更細緻處理
        return new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
    }

    // Getter/Setter 省略
    public String getInputPath() { return inputPath; }
    public void setInputPath(String inputPath) { this.inputPath = inputPath; }
    public String getFileName() { return fileName; }
    public void setFileName(String fileName) { this.fileName = fileName; }
}

前端 JSP 調用示例

<%@ taglib prefix="s" uri="/struts-tags" %>
<ul>
    <li><a href="<s:url action='downloadFile' namespace='/download'><s:param name='fileName'>dwr.jar</s:param></s:url>">dwr.jar 下載</a></li>
    <li><a href="<s:url action='downloadFile' namespace='/download'><s:param name='fileName'>Struts2教程.pdf</s:param></s:url>">Struts2教程.pdf 下載</a></li>
</ul>

struts.xml 配置詳解

<package name="download" namespace="/download" extends="struts-default">
    <action name="downloadFile" class="com.example.action.DownloadAction" method="downloadFile">
        <param name="inputPath">/upload</param>
        <result name="success" type="stream">
            <param name="contentType">application/octet-stream</param>
            <param name="inputName">inputStream</param>
            <param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
            <param name="bufferSize">4096</param>
        </result>
    </action>
</package>

關鍵屬性說明:

  • inputName:對應 Action 中 getInputStream() 方法(去掉 get 首字母小寫)。
  • contentDisposition:attachment 強制下載;filename 取自 getDownloadFileName()。
  • bufferSize:緩衝區大小,建議 4096 或 8192 提升大文件傳輸效能。

中文檔名編碼最佳實踐補充

不同瀏覽器對 Content-Disposition 編碼解析不一,生產環境建議使用 HttpServletResponse.setHeader 配合 URLEncoder.encode(fileName, "UTF-8") 並處理 User-Agent 差異,或引入 Content-Disposition 處理工具類(如 Spring 的 ContentDisposition)。

結語

掌握 Stream Result 機制與編碼轉換細節,即可在 Struts2 中穩健實現含中文文件名的下載功能。

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