问答1 问答5 问答50 问答500 问答1000

Struts1.x系列教程(15):使用DownloadAction类统计文件下载次数...

提问网友 发布时间:7小时前
声明声明:本网页内容为用户发布,旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:1656858193@qq.com
1个回答
热心网友 回答时间:2小时前

  除了标准的 apache struts action Action类外 在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响应消息头字段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程序 这个程序的基本原理是当一个文件下载完成后 加这个文件在数据库中的下载次数加 如果某个文件是第一次下载 则在数据库中添加一条新记录 下载次数为

  为了实现这个Web程序 需要如下几步

   【第 步】 建立用于保存文件下载次数的数据表

  在本例中我们使用名为struts数据库 并且在struts数据库中建立一个t_dcount表 代码如下

     CREATE TABLE struts t_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目录中建立一个FileDownloadAction java文件 代码如下

     package chapter action;    import javax servlet *;  import  apache struts action *;  import  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( mysql jdbc Driver );              conn = DriverManager getConnection(                       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 =   + String valueOf(id));          ResultSet rs = pstmt executeQuery();          while (rs next())          {              return rs getInt( );          }          return  ;      }      // 在文件完成下载后 将该文件的下载次数加       private void incDownloadCount() throws Exception      {          openConnection();          int id = filename hashCode();          PreparedStatement pstmt = conn                   prepareStatement( UPDATE t_dcount SET count = count +   WHERE id =                            + String valueOf(id));          if (pstmt executeUpdate() ==  )          {              pstmt executeUpdate( INSERT INTO t_dcount(id  count  filename) values(                               + String valueOf(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 ;          // 建议设置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  + 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);          }      }  }

   【第 步】 配置Struts动作类

  在struts config xml文件中的<action mappings>标签中加入了如下内容

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

   【第 步】 配置下载路径

  在web xml中找到一个叫action的Servlet 并在<servlet>标签中添加如下内容

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

  读取可以设置自已的下载目录 但下载目录必须以 结尾

  启动Tomcat后 在IE中输入如下的URL来测试程序

lishixinzhi/Article/program/Java/ky/201311/28413

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

亚洲杯爆大冷门 桐山在厦门什么方向 ...1961年1月26日出生,汉族,福鼎市人,住福鼎市桐山镇海口路。 福鼎火车站到桐山派出所怎么走? 张艺凡21岁生日,硬糖姐妹分分送祝福,她和陈卓璇两个人关系如何?_百度... 冰糖炖雪梨夏梦欢喜欢谁 夏梦欢结局和谁在一起了 这个是什么朝代的啊 新阳铺是谁的诗 工伤认定作出的时限为多少天,工伤认定作出的时限 自制蒸肠粉做法大全 蒸肠粉做法大全 城镇职工养老保险和城乡居民养老保险同时买可以吗 灌木是乔木吗? 灌木的植被特征 地下城堡2图5黑塔-地下城堡2图6白塔位置 网上的黑料怎么删除? 逻可以组什么词? 逻可从组什么词? 杜牧紫薇花原文及赏析 武汉哪里可以买大扶康针 氟康唑注射液 辉瑞制药有限公司 action对魔忍如何下载 老锐界后电尾门没反应是什么问题 短周期主族元素中最活泼的非金属元素 活泼的非金属元素主要集中在短周期吗 在运动速度和位置相同的情况下,地转偏向力的大小和物体运动方向有... 锡林郭勒职业学院有哪些官方网站 香云纱连衣裙新款图片及价格真丝香云纱连衣裙正品 须臾主父乘奔至的下一句须臾主父乘奔至的下一句是什么 绿色波点旗袍,新中式的魅力 硫酸亚铁肥可以直接施吗? 车标和耐克一个样子是什么车,横着椭圆型里面是和耐克一样的对勾,_百度... down和sorry的发音一样吗? 什么生肖克猪最厉害 iscreen不跳转 屁股上大火疖子,破了出脓,现在裂口处一团红,时不时流一点脓水,用无菌帖... 怎样求出无功功率的公式 宝宝发烧怎么办?这些小技巧帮你搞定! 宝宝发烧怎么办?护理小技巧全在这里! 慢性阑尾炎不能吃什么?慢性阑尾炎在饮食方面有什么需要忌口的?_百度... 女生为爱付出多少才能得到男生的疼爱呢?