熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Struts1.x系列教程(15):使用DownloadAction類統計文件下載次數

2013-11-23 20:23:03  來源: Java開源技術 

  除了標准的orgapachestrutsactionAction類外在Struts中還提供了另外個Action類來完成特殊的工作本文及後面的文章中將介紹這些Action類的用法

  DownloadAction類簡介

  可能有時需要在Web程序中加入下載功能如果要下載的是靜態文件可以直接交給Web服務器處理但如果要對下載的文件做額外的功能如統計文件的下載次數就需要在下載文件之前先要調用相應的程序進行處理

  雖然我們可以直接在Action子類中來處理下載文件但是如果這樣的程序比較多時就會寫很多重復的代碼為了簡化這個工作Struts提供了一個新的Action類DownloadAction所有繼承了DownloadAction類的Struts動作都可以非常容易地完成下載文件的工作

  DownloadAction類有一個抽象方法getStreamInfo這個方法的定義如下

     protected abstract StreamInfo getStreamInfo(ActionMapping mapping
                ActionForm form HttpServletRequest request
            HttpServletResponse response) throws Exception;

  getStreamInfo方法返回一個StreamInfo對象StreamInfo接口是DownloadAction類的一個內部接口這個接口的定義如下

   public static interface StreamInfo 
{
    public abstract String getContentType();
    public abstract InputStream getInputStream() throws IOException;
}

  從上面的代碼可以看出StreamInfo接口有兩個方法其中getInputStream方法返回了服務端要下載的文件的InputStream對象getContenttType方法返回了HTTP響應消息頭字段ContentType的信息在getStreamInfo方法中只要返回了實現這兩個方法的StreamInfo對象就可以自動完成下載工作

  為了方便起見DownloadAction類中還提供了兩個實現StreamInfo的內類FileStreamInfo和ResourceStreamInfo這兩個類的構造方法的定義如下

   public FileStreamInfo(String contentType File file);
  public ResourceStreamInfo(String contentType ServletContext context String path);

  我們可以使用FileStreamInfo類來下載靜態的文件如果要下載的文件在Web根目錄可以使用ResourceStreamInfo類其中path參數表示文件相對於Web根目錄的路徑必須以/開頭表示從Web根目錄開始

  實例統計文件的下載次數

  在本節中將使用DownloadAction類實現一個統計文件下載次數的Web程序這個程序的基本原理是當一個文件下載完成後加這個文件在數據庫中的下載次數加如果某個文件是第一次下載則在數據庫中添加一條新記錄下載次數為

  為了實現這個Web程序需要如下幾步

  【第步】建立用於保存文件下載次數的數據表

  在本例中我們使用名為struts數據庫並且在struts數據庫中建立一個t_dcount表代碼如下

     CREATE TABLE strutst_dcount(
  id INT NOT NULL
  count INT NOT NULL
  filename VARCHAR(  ) NOT NULL
  PRIMARY KEY (id)
  ) ENGINE = InnoDB  DEFAULT CHARSET=gbk;

  【第步】編寫Struts動作類

  這個Struts動作類負責完成文件的下載工作如果在訪問Struts動作類時不加file參數會將指定目錄下的所有文件(不包括隱藏文件)和已經下載的次數發送到客戶端浏覽器如果通過file參數指定了下載文件這個Struts動作就會下載這個文件

  在<samples工程目錄>\src\action目錄中建立一個FileDownloadActionjava文件代碼如下

     package chapteraction;
  
  import javaxservlethttp*;
  import orgapachestrutsaction*;
  import orgapachestrutsactions*;
  import javaio*;
  import javasql*;
  
  public class FileDownloadAction extends DownloadAction
  {
      private Connection conn;
      private String path;
      private String filename;
  
      // 獲得了Connection對象
      private void openConnection() throws Exception
      {
          if (conn == null)
          {
              ClassforName(commysqljdbcDriver);
              conn = DriverManagergetConnection(
                      jdbc:mysql://localhost/struts?characterEncoding=GBK
                      root );
          }
      }
      // 獲得某個文件的下載次數其中id是文件名的hashcode
      private int getDownloadCount(int id) throws Exception
      {
          openConnection();
          PreparedStatement pstmt = conn
                  prepareStatement(SELECT count FROM t_dcount WHERE id =  + StringvalueOf(id));
          ResultSet rs = pstmtexecuteQuery();
          while (rsnext())
          {
              return rsgetInt();
          }
          return ;
      }
      // 在文件完成下載後將該文件的下載次數加
      private void incDownloadCount() throws Exception
      {
          openConnection();
          int id = filenamehashCode();
          PreparedStatement pstmt = conn
                  prepareStatement(UPDATE t_dcount SET count = count +  WHERE id = 
                          + StringvalueOf(id));
          if (pstmtexecuteUpdate() == )
          {
              pstmtexecuteUpdate(INSERT INTO t_dcount(id count filename) values(
                              + StringvalueOf(id) +  + filename + ));
          }
      }
  
      // 下載文件時調用getStreamInfo方法
      protected StreamInfo getStreamInfo(ActionMapping mapping ActionForm form
              HttpServletRequest request HttpServletResponse response)
              throws Exception
      {
          final FileInputStream fis = new FileInputStream(path + filename);
          final String contentType = application/file;
          // 建議設置contentdisposition響應信息頭否則Web浏覽器在下載文件時
          // 無法在保存文件對話框中顯示正確的文件名
          responsesetHeader(contentdisposition attachment; filename=
                  + filename);
          incDownloadCount();
          return new DownloadActionStreamInfo()  // 使用隱式的方法實現了StreamInfo接口
          {
              public String getContentType()
              {
  
                  return contentType;
              }
              public InputStream getInputStream() throws IOException
              {
                  return fis;
              }
          };
      }
      // 如果Struts動作不加file請求參數則通過execute方法將指定目錄中文件列表輸出到客戶端
      public ActionForward execute(ActionMapping mapping ActionForm form
              HttpServletRequest request HttpServletResponse response)
              throws Exception
      {
          path = thisgetServlet()getInitParameter(downloadPath);
          filename = requestgetParameter(file);
          if (filename == null)
          {
              File file = new File(path);
              File[] files = filelistFiles();
              responsesetCharacterEncoding(GBK);
              PrintWriter out = responsegetWriter();
              
              outprintln(<ul>);
              for (File f : files) // 開始向客戶端浏覽器輸出文件列表 
              {
  
                  if (fisFile() && !fisHidden())
                  {
                      outprintln(<li><a  + requestgetContextPath() + mappinggetPath()
do?file= + fgetName() + > + fgetName()
                               + </a>&nbsp;&nbsp;<font color=blue>下載次數
                              + StringvalueOf(getDownloadCount(fgetName()hashCode())) 
</color></li>);
                  }
              }
              outprintln(</ul>);
              return null;
          }
          else
          {
              // 當file參數存在時則調用DownloadAction中的execute方法
              // 實際上在DownloadAction類中的execute方法調用了getStreamInfo方法
              // 這條語句就相當於調用了getStreamInfo方法
              return superexecute(mapping form request response);
          }
      }
  }

  【第步】配置Struts動作類

  在strutsconfigxml文件中的<actionmappings>標簽中加入了如下內容

   <action path=/download scope=request type=actionFileDownloadAction />

  【第步】配置下載路徑

  在webxml中找到一個叫action的Servlet並在<servlet>標簽中添加如下內容

   <initparam>
    <paramname>downloadPath</paramname>
    <paramvalue>D:\download\</paramvalue>
</initparam>

  讀取可以設置自已的下載目錄但下載目錄必須以結尾

  啟動Tomcat後在IE中輸入如下的URL來測試程序

  


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28413.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.