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

Struts2 實現文件上傳與下載完整實例解析

     編輯:Java 相關知識

Struts2 文件上傳功能實現

1. JSP 頁面上傳表單

在 JSP 頁面中定義一個文件上傳輸入框,注意表單必須設置 enctype="multipart/form-data":

<tr>
  <td align="right" bgcolor="#F5F8F9"><b>附件:</b></td>
  <td bgcolor="#FFFFFF">
    <input type="file" name="upload" />
  </td>
  <td bgcolor="#FFFFFF"> </td>
</tr>

2. Action 基類屬性定義

在 BaseAction 中聲明接收上傳文件所需的屬性:

public class BaseAction extends ActionSupport {
    protected List<File> upload;
    protected List<String> uploadContentType; // 文件類型
    protected List<String> uploadFileName;    // 文件名
    protected String savePath;                // 保存路徑
}

3. 上傳處理方法

在具體 Action 中實現上傳邏輯,遍歷文件列表並寫入磁盤:

public void uploadAccess(List<File> upload) {
    try {
        if (null != upload) {
            for (int i = 0; i < upload.size(); i++) {
                String path = getSavePath() + getUploadFileName().get(i);
                item.setAccessory(getUploadFileName().get(i));
                FileOutputStream fos = new FileOutputStream(path);
                FileInputStream fis = new FileInputStream(getUpload().get(i));
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = fis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fis.close();
                fos.close();
            }
        }
    } catch (Exception e) {
        logger.error("上傳附件失敗。", e);
    }
}

4. struts.xml 配置上傳攔截器

配置 fileUpload 攔截器限制文件類型與大小:

<action name="itemRDAction_*" class="itemRDAction" method="{1}">
  <param name="savePath">e:upload</param>
  <interceptor-ref name="defaultStack">
    <param name="fileUpload.allowedTypes">
      application/octet-stream,image/pjpeg,image/bmp,image/jpg,image/png,image/gif,image/jpeg,
      application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,
      application/vnd.ms-excel
    </param>
    <param name="fileUpload.maximumSize">8000000</param>
  </interceptor-ref>
  <result name="show_item_rd_upd">/WEB-INF/jsp/page_item/updItem_rd.jsp</result>
  <result name="show_item_rd_list">/WEB-INF/jsp/page_item/listItem_rd.jsp</result>
  <result name="show_item_rd_push">/WEB-INF/jsp/page_item/pushItem_rd.jsp</result>
</action>

Struts2 文件下載功能實現

1. 頁面下載鏈接

使用 JSTL 判斷附件是否存在並生成下載連結:

<tr>
  <td width="20%" align="right" bgcolor="#F5F8F9"><b>附件:</b></td>
  <td width="40%" bgcolor="#FFFFFF">
    <div>${item.accessory}</div>
    <c:if test="${!empty item.accessory}">
      <div class="btn_img"><a href="download.action?filename=${item.accessory}">下載</a></div>
    </c:if>
  </td>
  <td width="40%" bgcolor="#FFFFFF"> </td>
</tr>

2. DownloadAction 處理下載

繼承 BaseAction,實現 getInputStream() 返回文件輸入流,並處理中文文件名編碼:

@Controller("downloadAction")
@Scope("prototype")
public class DownloadAction extends BaseAction {
    private String filename;
    private InputStream inputStream;
    private String savePath;
    private String mimeType;

    public InputStream getInputStream() {
        try {
            String path = getSavePath() + "//" + new String(filename.getBytes("ISO8859-1"), "utf-8");
            mimeType = ServletActionContext.getServletContext().getMimeType(path) + ";charset=UTF-8";
            inputStream = new FileInputStream(path);
            String agent = ServletActionContext.getRequest().getHeader("USER-AGENT");
            if (null != agent) {
                if (-1 != agent.indexOf("Firefox")) {
                    mimeType = mimeType.replace("UTF-8", "ISO8859-1");
                } else {
                    filename = new String(filename.getBytes("ISO8859-1"), "utf-8");
                    filename = java.net.URLEncoder.encode(filename, "UTF-8");
                }
            }
        } catch (Exception e) {
            logger.error("下載文件信息失敗。", e);
        }
        return inputStream;
    }
    // getter/setter 省略
}

3. struts.xml 配置流結果類型

<action name="download" class="downloadAction">
  <param name="savePath">E:/upload</param>
  <result type="stream">
    <param name="contentType">${mimeType}</param>
    <param name="contentDisposition">attachment;filename="${filename}"</param>
    <param name="inputName">inputStream</param>
  </result>
</action>

大文件上傳常見問題與解決方案

問題現象

上傳大文件時出現錯誤:the request was rejected because its size exceeds the configured maximum。

解決步驟

  1. 設置臨時存儲目錄:在 struts.properties 中添加 struts.multipart.saveDir=/temp。
  2. 調整最大上傳大小:在 struts.properties 或 struts.xml 中設置 struts.multipart.maxSize(單位字節)。
  3. Action 級配置攔截器:在 struts.xml 中為具體 Action 顯式引用 fileUpload 攔截器並設置 maximumSize,同時配置 input 結果頁面。
  4. 捕獲異常並轉為用戶友好提示:重寫 addActionError 方法,解析異常信息並設置自定義錯誤消息,前端通過 <s:fielderror/> 或 JS 彈窗顯示。

關鍵配置差異說明

  • struts.multipart.maxSize:控制整個項目允許的最大請求大小,默認 2MB。
  • fileUpload.maximumSize:單個 Action 級別的文件大小限制,必須小於 struts.multipart.maxSize。
  • 當上傳文件大小介於兩者之間時,系統提示 File too large;超過 struts.multipart.maxSize 則直接報錯。

文件類型限制配置

通過自定義攔截器棧 myDefaultStack 在 fileUpload 攔截器中設置 allowedTypes 參數,然後在 <package> 中設置為默認攔截器棧,或在具體 Action 中引用。

<interceptors>
  <interceptor-stack name="myDefaultStack">
    <interceptor-ref name="fileUpload">
      <param name="allowedTypes">image/png,image/gif,image/jpeg</param>
    </interceptor-ref>
    ... 其他攔截器 ...
  </interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStack" />

注意:上傳表單必須包含 enctype="multipart/form-data",否則會直接進入 input 結果。

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