调查一个 pdf 打印报错:

ExceptionConverter: org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:407)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:432)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:420)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
at java.io.BufferedOutputStream.write(Unknown Source)
at com.itextpdf.text.pdf.OutputStreamCounter.write(OutputStreamCounter.java:157)
at java.io.ByteArrayOutputStream.writeTo(Unknown Source)
at com.itextpdf.text.pdf.PdfStream.toPdf(PdfStream.java:353)
at com.itextpdf.text.pdf.PdfIndirectObject.writeTo(PdfIndirectObject.java:157)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:396)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:376)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:329)
at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:780)
at com.itextpdf.text.pdf.TrueTypeFontUnicode.writeFont(TrueTypeFontUnicode.java:385)
at com.itextpdf.text.pdf.FontDetails.writeFont(FontDetails.java:274)
at com.itextpdf.text.pdf.PdfWriter.addSharedObjectsToBody(PdfWriter.java:1249)
at com.itextpdf.text.pdf.PdfWriter.close(PdfWriter.java:1169)
at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:780)
at com.itextpdf.text.Document.close(Document.java:409)

可以看到 在 调用 pdf 的 Document.close() 方法时,抛出了上诉错误。

调试之后的原因是,在chrome浏览器中页面上 点击一次 打印,打印 servlet 会执行两次,第一次 可以正常打印,document.close() 可以正常执行,没有报错,可以执行完了之后,servlet又一次执行了!所以在第二次 document.close() 时,报错:

ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error

原因是,浏览器已经关闭了连接,所以第二次 向浏览器输出 :

response.setContentType("application/pdf");

时,才报错。

发现只有 chrome才存在这个问题。调查的结果:

-----------------------------------------------------------------------------------------

http://blog.lifw.org/post/66162597

贴下全文:

chrome等浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常

博主在写一篇关于文件下载的博文 http://blog.lifw.org/post/24251622 时,遇到了一个很恶心的问题,现象是我在 chrome 以及 Safari 浏览器地址栏直接输入文件下载链接 localhost:8080/download 时,我的 download 方法被请求了两次,并且第一次抛出如下的 ClientAbortException 异常

然后 chrome 了很多资料,最后终于找到原因:由于 chrome、Safari 等浏览器为了使网页加载更快,使用了一种叫做预提取资源,以便更快速地加载网页机制,也就是说当你在浏览器中输入 url 后,即便你还没回车发送请求,浏览器也会预先发送请求加载资源,因此每当我在地址栏中输入 url localhost:8080/download 时,浏览器便发送请求到我的 download 方法中,然后我的 download 方法给浏览器返回一个文件下载响应,此时,浏览器一看是文件下载,不能预先加载,因此便主动关闭了链接,便导致了ClientAbortException 异常,然后我回车真正发送了该请求,浏览器便会下载文件,此时没有异常,文件下载成功。综上所诉,便导致 chrome 一个请求发送两次的现象。

网上查找资料的过程中,看到有的人在做计数统计的时候,如果使用 chrome,则每次请求会计数两次,其实也是该问题导致的,因此如果你在开发的过程中,如果莫名其妙的遇到一个请求发送多次的问题,不妨往这方面考虑一下,关闭 chrome 的预提取资源功能测试一下,往往便能解决问题。这个问题非常恶心,并且不易察觉,希望本文能对后来人有所帮助。

 

chrome 浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常的更多相关文章

  1. Chrome浏览器中使用 iframe 嵌入网页导致视频不能全屏的问题解决方法

    今天无意中测试了下在 iframe 中嵌入视频, 发现全屏按钮在 Chrome 浏览器中居然无效, 试了好几个视频网站的视频都不能全屏, 但在其他浏览器中似乎都很正常, 应该是 Chrome 60 新 ...

  2. [转] Chrome - 浏览器跨域访问设置(附:新老版本两种设置方法)

    [From] http://www.hangge.com/blog/cache/detail_1703.html 在进行前后分离的 webapp 开发,或者 H5 移动 App 开发时,我们会使用 P ...

  3. jmeter从上一个请求使用正则表达式抓取Set-Cookie值,在下一个请求中运用

    工作中遇到的问题,登录请求,返回的Response Headers中有个参数Set-Cookie,需要抓取这个参数,运用到下一个请求中,见下图: 通过正则表达式抓取Set-Cookie的值,由于该值存 ...

  4. selenium+chrome浏览器驱动-爬取百度图片

    百度图片网页中中,当页面滚动到底部,页面会加载新的内容. 我们通过selenium和谷歌浏览器驱动,执行js,是浏览器不断加载页面,通过抓取页面的图片路径来下载图片. from selenium im ...

  5. Hystrix熔断机制导致误报请求超时错误

    问题的过程如下: (1)前端向服务端请求往HBase插入1000条数据: (2)请求经路由网关Zuul传递给HBaseService,HBaseService执行插入操作: (3)插入操作需要的时间超 ...

  6. 借助Chrome和插件爬取数据

    工具 Chrome浏览器 TamperMonkey ReRes Chrome浏览器 chrome浏览器是目前最受欢迎的浏览器,没有之一,它兼容大部分的w3c标准和ecma标准,对于前端工程师在开发过程 ...

  7. Chrome浏览器扩展开发系列之九:Chrome浏览器的chrome.alarms.* API

    Chrome浏览器扩展程序通过chrome.alarms.* API,可以制定计划周期性地执行代码,或在指定时间执行代码. 要使用chrome.alarms.* API,首先需要在manifest.j ...

  8. Chrome浏览器扩展开发系列之五:Page Action类型的Chrome浏览器扩展

    Page Action类型的Google Chrome浏览器扩展程序,通常也会有一个图标,但这个图标位于Chrome浏览器的地址栏内右端.而且这个图标并非始终出现,而是当某指定的页面打开时才会出现.也 ...

  9. Chrome浏览器断点调试无效的问题

    问题是这样的,在使用chrome浏览器调试JavaScript的时候,突然设置的断点失效了,怎么弄都没有效果. 折腾了半天,尝试了各种方法就是没有用. 解决:重启一下chrome浏览器就好了,这似乎是 ...

随机推荐

  1. Angularjs promise对象解析

    1.先来看一段Demo,看完这个demo你可以思考下如果使用$.ajax如何处理同样的逻辑,使用ng的promise有何优势? var ngApp=angular.module('ngApp',[]) ...

  2. JS实现返回对象的详细信息

    使用JS有时会需要打印出对象的详细信息,下面方法可以实现: function ShowObjProperty(Obj) { var PropertyList=''; var PropertyCount ...

  3. 一个基于mysql构建的队列表

    通常大家都会使用redis作为应用的任务队列表,redis的List结构,在一段进行任务的插入,在另一端进行任务的提取. 任务的插入 $redis->lPush("key:task:l ...

  4. Github团队开发示例(二)

    Github团队开发示例(二) 作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/6063765.html 接之前讲的Github团队开发示例(一),本文主 ...

  5. 在 C# 中执行 msi 安装

    有时候我们需要在程序中执行另一个程序的安装,这就需要我们去自定义 msi 安装包的执行过程. 需求 比如我要做一个安装管理程序,可以根据用户的选择安装不同的子产品.当用户选择了三个产品时,如果分别显示 ...

  6. 五小步让VS Code支持AngularJS智能提示

    本文想通过配置VS Code来实现对AngularJS的智能提示.在一般的情况下对于在HTML页面是支持提示的.但是在js页面就不是很友好,它是记忆你之前的输入,要是之后有重复的输入,VS Code会 ...

  7. Nancy之给我们的网站添加自定义图标

    当我们在做一个网站时,可能经常会有这样一个需求,要给我们做的网站添加一个自定义的图标. 在Nancy中,默认是的下面这样 一个妹子的头像,其实也是挺好看的!! 那么当我们想要替换这个默认的,应该要怎么 ...

  8. C#基础知识四之override和new的区别

    override override是派生类用来重写基类方法的.调用的派生类方法,如需调用基类方法用base关键字 override不能重写非虚方法或静态方法. override重写必须用abstrac ...

  9. 从零开始编写属于我的CMS:(六)插件

    二三四五还没写,先写六吧(有道友说想看看插件部分). 这里是一 从零开始编写属于我的CMS:(一)前言 一,首先预定义接口 新建类库,WangCms.PluginInterface 新建两个类,一个实 ...

  10. 【JAVA并发编程实战】9、锁分段

    package cn.study.concurrency.ch11; /** * 锁分段 * @author xiaof * */ public class StripedMap { //同步策略:就 ...