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

Struts 1.x 系列教程(15):DownloadAction 實作檔案下載計次統計

     編輯:Java 相關知識

前言

DownloadAction 為 Struts 內建支援檔案下載的抽象類別。子類別只需實作 getStreamInfo() 回傳 StreamInfo(含 Content-Type 與 InputStream),框架自動處理下載回應。本文示範結合資料庫統計下載次數的完整範例。

核心介面與輔助類別

// DownloadAction 內部介面
public static interface StreamInfo {
    String getContentType();
    InputStream getInputStream() throws IOException;
}

// 兩個便利實作
public FileStreamInfo(String contentType, File file);           // 本地檔案
public ResourceStreamInfo(String contentType, ServletContext ctx, String path); // Web 根目錄下資源

完整範例:FileDownloadAction

資料表 t_dcount

CREATE TABLE struts.t_dcount (
    id INT NOT NULL PRIMARY KEY,
    count INT NOT NULL,
    filename VARCHAR(256) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

id 使用檔名 hashCode() 作為主鍵。

Action 類別實作

package action;
import org.apache.struts.actions.DownloadAction;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;

public class FileDownloadAction extends DownloadAction {
    private Connection conn;
    private String basePath;   // 來自 web.xml init-param
    private String filename;   // 來自請求參數 file

    // 延遲建立資料庫連線
    private void openConnection() throws Exception {
        if (conn == null) {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(
                "jdbc:mysql://localhost/struts?characterEncoding=GBK", "root", "1234");
        }
    }

    // 查詢下載次數
    private int getDownloadCount(int id) throws Exception {
        openConnection();
        PreparedStatement ps = conn.prepareStatement(
            "SELECT count FROM t_dcount WHERE id = " + id);
        ResultSet rs = ps.executeQuery();
        return rs.next() ? rs.getInt(1) : 0;
    }

    // 遞增下載次數(不存在則插入)
    private void incDownloadCount() throws Exception {
        openConnection();
        int id = filename.hashCode();
        PreparedStatement ps = conn.prepareStatement(
            "UPDATE t_dcount SET count = count + 1 WHERE id = " + id);
        if (ps.executeUpdate() == 0) {
            ps.executeUpdate(
                "INSERT INTO t_dcount(id, count, filename) VALUES(" + id + ", 1, '" + filename + "')");
        }
    }

    // 核心:提供下載串流資訊
    protected StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form,
                                       HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        FileInputStream fis = new FileInputStream(basePath + filename);
        String contentType = "application/file";
        // 關鍵:設定 Content-Disposition 讓瀏覽器顯示正確檔名
        response.setHeader("content-disposition", "attachment; filename=" + filename);
        incDownloadCount(); // 統計
        return new StreamInfo() { // 匿名實作
            public String getContentType() { return contentType; }
            public InputStream getInputStream() throws IOException { return fis; }
        };
    }

    // 無 file 參數時:列出目錄檔案與下載次數
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        basePath = getServlet().getInitParameter("downloadPath");
        filename = request.getParameter("file");
        if (filename == null) {
            File dir = new File(basePath);
            File[] files = dir.listFiles();
            response.setCharacterEncoding("GBK");
            PrintWriter out = response.getWriter();
            out.println("
    "); for (File f : files) { if (f.isFile() && !f.isHidden()) { out.println("
  • " + f.getName() + "  下載次數:" + getDownloadCount(f.getName().hashCode()) + "
  • "); } } out.println("
"); return null; } else { return super.execute(mapping, form, request, response); // 觸發 getStreamInfo } } }

配置步驟

  1. struts-config.xml:
    <action path="/download" scope="request" type="action.FileDownloadAction" />
  2. web.xml 於 action Servlet 加入初始化參數:
    <init-param>
        <param-name>downloadPath</param-name>
        <param-value>D:\download\</param-value>  <!-- 必須以反斜線結尾 -->
    </init-param>
  3. (可選)struts-config.xml 設定 <controller maxFileSize="2M"/> 限制上傳大小(不影響下載)。

測試

訪問 https://localhost:8080/samples/download.do 列出檔案清單,點選連結下載並自動統計次數。

總結

DownloadAction 封裝了下載回應的標準流程,開發者專注於提供 InputStream 與 Content-Type,並能輕鬆插入統計、權限檢查等業務邏輯。注意設定 content-disposition 標頭確保瀏覽器正確顯示下載檔名。

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