浏览器发送总共下载文件2第二个请求,如何“下载”仅仅记录1次要?

近期,个人官网实现了PDF下载功能,出于统计的考虑。添加了“下载次数”download_count这个字段。

可是。我今天突然发现。每次下载download_count都直接+2了。假设server发生这样的事,另一定的可能,本地就我一个人下载,怎么可能下载2次。

于是,打开了log4j的debug模式。果然运行了2次更新请求。

@RequestMapping(value = "/download/pdf")

public void downloadPdf(@RequestParam Integer id, HttpServletRequest req,

HttpServletResponse res) {

Map<String, Object> article = articleService.get(id);

PdfDownload.doDownloadPdfPostWithShuiyin(req, res, article);
                articleService.plusDownloadCount(id);
    }

于是,想通过ThreadLocal<Integer> local;这样的方式去记录。假设local中有值,表明当前线程已经下载过了,不须要再次更新下载次数。

但事实证明,上述做法不对,实际现象是次数添加不够“稳定”,有时+1。有时+2。

后来,我又把local中的值。存放ip,推断是否为null,或者2次请求ip是否同样。结果仍然不够“稳定”。
--------------------------------------------------------
在实践过程中,我的一些“误解”:
1.下载文件,浏览器仅仅会发送1次请求。实际是2次,毫无疑问。
2.发送2次请求,是同一个线程响应。我想当然的觉得这2次请求,都是服务于“同一次下载”。
  事实证明,我太天真。
3.因为觉得这2次请求。我觉得使用ThreadLocal存放个值,表明当前线程已经下载过了。
  事实证明。这不科学。

2次请求。2个不同的线程响应。
4.“2次请求,2个不同的线程响应。

”理论上是这样。
   但我们Team在做公司项目的时候,遇到了相似的问题。Boss后来想起来,Tomcat的线程是用“线程池” 实现的。

多次请求可能是同一个线程处理,也可能是多个。 
  这一点。和实际发生的“更新次数不稳定” 很吻合。
5.下载文章A,次数更新。

下载文章B、C、D,次数都不再更新。
  这个不符合我的设想,原因是:下载没有比較文章的ID,不同文章的下载次数应该是相互独立的。

--------------------------------------------------------
如今有2个问题:
1.我就想实现自己最初的想法。

浏览器发送2次请求,下载次数更新了2次。能不能仅仅让它更新一次了。从而准确地体现下载次数!!。
  这个我眼下还没有想到好的方法。

2. 改变需求,一个用户在一定时期内,下载一篇文章,不管多少次。都仅仅算一次。

下载不同的文章,次数应该且仅仅应该添加1次。

我的想法:
  建立一个存放已经下载的队列,用户的ip和文章的id共同作为key。
  用户下载一次,就把用户IP和文章ID 共同组成的key,存放到队列里。
  当来了新的下载请求时。从队列中查找,是否已经存在key。假设不存在。才+1.否则。不更新次数。

原文首发:http://fansunion.cn/article/detail/141.html

时间: 2024-11-05 20:32:18

浏览器发送总共下载文件2第二个请求,如何“下载”仅仅记录1次要?的相关文章

Android中AsyncTask进行后台下载文件并在下拉菜单显示下载进度

在开发过程中,总会需要从网络上下载文件,有时候还需要将下载进度显示在下拉菜单中. 现在写了一个Demo,封装了AsyncTask下载文件和进度显示的代码,以后在做项目的时候能够直接进行使用. 效果图: 主界面只有一个按钮,比较简单: / layout / activity_main.xml : <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="h

springboot项目下载文件功能中-切面-导致的下载文件失败的bug

背景:使用spring提供的 ResponseEntity 和Resource结合,实现的下载文件功能 bug:Resource已经加载到了文件, 并且通过 ResponseEntity 构建了响应,但是页面接收不到文件. 原因:目前初步发现是因为我使用的捕获异常的切面导致的,具体切面怎么会导致 响应结构 的改变,暂时没有搞明白,后续研究透了再补充 解决办法:把下载文件的接口排除在切面处理的范围外,就好了. 吃一堑长一智:浪费了差不多一天的时间在这个问题上,很苦恼,希望下次能使用排除法,更高效的

Unity下载文件一(www协程下载)

下载功能,是大多数游戏或者软件都需具备的一个基础模块,但是很多人却没有机会去写这个完整功能. 那么我就分享下我写该功能时的随笔整理 本文只说www协程下载,http的同步和异步下载放到下篇 这个简单: WWW wwwServer = new WWW("http://192.168.1.1:8080/Files/ab.assetBundle"); yield return wwwServer; if (string.IsNullOrEmpty(wwwServer.error)) { As

通知浏览器下载文件,而不是直接打开下载

1 // 1.获取要下载的文件的绝对路径 2 String realPath = this.getServletContext().getRealPath("/download/泉州行政区图0.jpg"); 3 System.out.println(realPath); 4 // 2.获取要下载的文件名 5 String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); 6 // 3.设置c

查看firefox浏览器 驱动geckodriver.exe文件的版本号的方法,以及下载链接

1-进入到geckodriver.exe文件的目录: 2-在路径栏下输入cmd: 3-命令行界面下输入:geckodriver.exe -h 可以看到文件的帮助信息,其中第一行就列出了版本号 为0.19.1 4-geckodriver驱动文件历史版本的下载链接: https://github.com/mozilla/geckodriver/releases 原文地址:https://www.cnblogs.com/xiaxiaoxu/p/9343971.html

.net中 登录 才能下载文件的方法 Response.WriteFile实现下载

protected void Button2_Click(object sender, EventArgs e) { //可以在这里加是否登录的判断 string fileName = "chracater14.jpg";//客户端保存的文件名 (其他文件格式都支持) string filePath = Server.MapPath("../../images/chracater14.jpg");//路径 FileInfo fileInfo = new FileIn

Win10系统IE浏览器能打开网页但无法下载文件的处理方法

在Win10系统中,很多没有安装下载软件的朋友默认就是使用IE来下载文件的,不过部分用户发现使用IE下载时出现点击无反应,无法下载的情况,那么如何解决此类问题呢?原因分析:出现此类情况大多是由于默认下载文件夹不存在引起的具体有如下几种方面.1.Win10系统安装好后修改了系统盘符修改系统盘符,IE浏览器默认的安装位置出现错误,导致IE无法运行,因此无法下载.建议:检查皇冠现金系统盘符是否和安装时的是一致的,若发生变化,把盘符重新改回和原来一致.2.默认下载文件夹不存在默认下载文件夹不存在,IE下

Unity3d C# Socket 下载文件 (同步到)

续篇 Unity3d C# HttpWebRequest 异步下载文件 ,由于project编译为IL2CPP的情况下仍然无效.提示HttpWebrequest 在当前版本号不支持.所以还是寻求其他的办法. 正好分公司的同事也碰到了下载文件的BUG,可是他们是仅仅可下面载一部分,好歹也比我的情况好,于是借同事的參考咯. 结构大致是用Socket 向server发送Http请求.再设置各种Http头,然后接收server发来的数据流. 先了解下Http头: 典型的请求消息: GET http://

Linux curl 命令下载文件

引用自http://blog.csdn.net/wh211212/article/details/54285921 命令:curl 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具. 语法:# curl [option] [url] 常见参数: -A/--user-agent <string> 设置用户代理发送给服务器 -b/--cookie <name