调查一个 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. Web接口测试工具---Poster与Postman

    工作当中有不少时间在编写和维护接口自动化测试用例.打算先整理一些接口相关工具的使用. 简单对接Web口测试的相关工具/技术做个划分. HTTP/SOAP协议接口的功能测试: 1.浏览器URL(GET请 ...

  2. AnagularJs之directive

    前言: 昨日周六,再登梧桐山.六点半,起.未到顶,雨纷飞.冒雨行,终封顶,只为合照一张.五点半,下山行.聆听大自然的律动,双腿随其自然而颤抖!今早起,我的双腿犹如叛逆期的少年,或如领家的孩童,遂决定今 ...

  3. 3.Struts2配置文件标签介绍

    Struts2的很多核心功能都是由拦截器实现的. struts-default.xml中定义了这些拦截器与Result类型. 所以,不继承struts-default包,Struts2提供的很多核心功 ...

  4. 使用webstom或者idea上传代码到github或coding

    鉴于github网络速度太慢,建议用coding.先介绍github上传方式,因为webstom或idea集成了github,方法简单. git是一个版本控制器,他的作用是管理代码.比如你修改了代码, ...

  5. sessionid如何产生?由谁产生?保存在哪里?

    面试问道这个我居然不知道怎么回答,当然也是因为我确实没有研究过.下面就是百度了一篇文章后简单回答这个问题. 参考:http://www.cnblogs.com/sharpxiajun/p/339560 ...

  6. mybatis入门基础(三)----SqlMapConfig.xml全局配置文件解析

    一:SqlMapConfig.xml配置文件的内容和配置顺序如下 properties(属性) settings(全局配置参数) typeAiases(类型别名) typeHandlers(类型处理器 ...

  7. MVC学习笔记1

    1. Action 如果返回的是自定义的引用类型,则默认返回的是类名,其实就是调用了类的tostring方法. 2. @Html.Partial用于将分部视图渲染为字符串 @{Html.RenderP ...

  8. 浅谈SQL Server中的三种物理连接操作

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  9. ASP.NET 5 已死 - 隆重介绍 ASP.NET Core 1.0 和 .NET Core 1.0

    还没正式登场就死了?不能怪我标题党,是大神Scott在他博客上这么说的,我只是翻译了一下. 在1月20号最新的ASP.NET Community Standup视频中,微软aspnet开发组的大帅哥 ...

  10. 查找html节点的方法

    document.firstChild document.documentElement(兼容性较好) 查找body节点的方法 document.firstChild.lastChild docume ...