<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

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

    本文為原創,如需轉載,請注明作者和出處,謝謝!

    上一篇:Struts1.x系列教程(14):動態Form

        除了標準的
    org.apache.struts.action.Action類外,在Struts中還提供了另外7Action類來完成特殊的工作。本文及后面的文章中將介紹這些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響應消息頭字段Content-Type的信息。在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程序。這個程序的基本原理是當一個文件下載完成后,加這個文件在數據庫中的下載次數加1,如果某個文件是第一次下載,則在數據庫中添加一條新記錄,下載次數為1

    為了實現這個Web程序,需要如下幾步:
      【第1步】建立用于保存文件下載次數的數據表

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

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

    【第2步】編寫Struts動作類

    這個Struts動作類負責完成文件的下載工作。如果在訪問Struts動作類時不加file參數,會將指定目錄下的所有文件(不包括隱藏文件)和已經下載的次數發送到客戶端瀏覽器。如果通過file參數指定了下載文件,這個Struts動作就會下載這個文件。
        在<samples工程目錄>\src\action目錄中建立一個FileDownloadAction.java文件,代碼如下:

      package chapter6.action;
      
      
    import javax.servlet.http.*;
      
    import org.apache.struts.action.*;
      
    import org.apache.struts.actions.*;
      
    import java.io.*;
      
    import java.sql.*;
      
      
    public class FileDownloadAction extends DownloadAction
      {
          
    private Connection conn;
          
    private String path;
          
    private String filename;
      
          
    // 獲得了Connection對象
          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");
              }
          }
          
    // 獲得某個文件的下載次數,其中id是文件名的hashcode
          private int getDownloadCount(int id) throws Exception
          {
              openConnection();
              PreparedStatement pstmt 
    = conn
                      .prepareStatement(
    "SELECT count FROM t_dcount WHERE id = " + String.valueOf(id));
              ResultSet rs 
    = pstmt.executeQuery();
              
    while (rs.next())
              {
                  
    return rs.getInt(1);
              }
              
    return 0;
          }
          
    // 在文件完成下載后,將該文件的下載次數加1
          private void incDownloadCount() throws Exception
          {
              openConnection();
              
    int id = filename.hashCode();
              PreparedStatement pstmt 
    = conn
                      .prepareStatement(
    "UPDATE t_dcount SET count = count + 1 WHERE id = "
                              
    + String.valueOf(id));
              
    if (pstmt.executeUpdate() == 0)
              {
                  pstmt.executeUpdate(
    "INSERT INTO t_dcount(id, count, filename) values("
                                  
    + String.valueOf(id) + ",1,'" + 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";
              
    // 建議設置content-disposition響應信息頭,否則Web瀏覽器在下載文件時
              
    // 無法在保存文件對話框中顯示正確的文件名
              response.setHeader("content-disposition""attachment; filename="
                      
    + filename);
              incDownloadCount();
              
    return new DownloadAction.StreamInfo()  // 使用隱式的方法實現了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 
    = this.getServlet().getInitParameter("downloadPath");
              filename 
    = request.getParameter("file");
              
    if (filename == null)
              {
                  File file 
    = new File(path);
                  File[] files 
    = file.listFiles();
                  response.setCharacterEncoding(
    "GBK");
                  PrintWriter out 
    = response.getWriter();
                  
                  out.println(
    "<ul>");
                  
    for (File f : files) // 開始向客戶端瀏覽器輸出文件列表 
                  {
      
                      
    if (f.isFile() && !f.isHidden())
                      {
                          out.println(
    "<li><a href='" + request.getContextPath() + mapping.getPath()
    + ".do?file=" + f.getName() + "'>" + f.getName()
                                   
    + "</a>&nbsp;&nbsp;<font color='blue'>下載次數:"
                                  
    + String.valueOf(getDownloadCount(f.getName().hashCode())) 
    + "</color></li>");
                      }
                  }
                  out.println(
    "</ul>");
                  
    return null;
              }
              
    else
              {
                  
    // 當file參數存在時,則調用DownloadAction中的execute方法
                  
    // 實際上,在DownloadAction類中的execute方法調用了getStreamInfo方法
                  
    // 這條語句就相當于調用了getStreamInfo方法
                  return super.execute(mapping, form, request, response);
              }
          }
      }

    【第3步】配置Struts動作類

        在struts-config.xml文件中的<action-mappings>標簽中加入了如下內容:

    <action path="/download" scope="request" type="action.FileDownloadAction" />

    【第4步】配置下載路徑   

    在web.xml中找到一個叫action的Servlet,并在<servlet>標簽中添加如下內容:

    <init-param>
        <param-name>downloadPath</param-name>
        <param-value>D:\download\</param-value>
    </init-param>

        讀取可以設置自已的下載目錄,但下載目錄必須以“"”結尾。
       
    啟動Tomcat后,在IE中輸入如下的URL來測試程序:

    http://localhost:8080/samples/download.do

    下一篇:Struts1.x系列教程(16):使用LocaleAction類實現國際化的Web程序





    Android開發完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2009-02-18 10:34 銀河使者 閱讀(3342) 評論(0)  編輯  收藏 所屬分類: javaweb 原創struts1.x

    主站蜘蛛池模板: 日日噜噜噜噜夜夜爽亚洲精品| 亚洲av无码成人精品国产| 哒哒哒免费视频观看在线www | 老汉精品免费AV在线播放| 国产亚洲人成在线播放| 亚洲国产电影在线观看| 亚洲av无码片在线播放| 免费一级毛片在线观看| 处破痛哭A√18成年片免费| 久久午夜羞羞影院免费观看| 五月天婷婷精品免费视频| 色偷偷尼玛图亚洲综合| 亚洲AV无码精品蜜桃| 亚洲精品在线不卡| 久久精品亚洲视频| 亚洲国产精品无码久久SM| 亚洲男人第一无码aⅴ网站| 国产精品自在自线免费观看| 国产美女在线精品免费观看| 18pao国产成视频永久免费| 久草视频在线免费看| 免费人成在线观看视频高潮| 一级做a爰全过程免费视频毛片| 激情婷婷成人亚洲综合| 亚洲日韩国产AV无码无码精品| 亚洲av极品无码专区在线观看| 亚洲系列中文字幕| 亚洲精品在线免费看| 亚洲高清中文字幕综合网| 亚洲第一区香蕉_国产a| 亚洲V无码一区二区三区四区观看| 国产av无码专区亚洲国产精品| 亚洲国产人成精品| 亚洲天堂中文字幕在线| 亚洲国产黄在线观看| 国产黄色一级毛片亚洲黄片大全| 亚洲不卡无码av中文字幕| 免费在线不卡视频| 中文字幕在亚洲第一在线| 亚洲伊人久久大香线蕉综合图片| 中文字幕亚洲日韩无线码|