解决Java使用response下载文件报错,并总结可能出错的原因: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

简介: 笔记

前言


前几天写了一个下载接口,当时用的uuid作为作为压缩包名称,需求觉得不妥,然后让换成从数据库里面查出来的某一段标题作为压缩包名称

换成中文之后呢,简单调试了下,我擦!报错了!1.png

赶紧去控制台查看日志

java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

2.png

发现并解决问题


此时我们的代码是这样的

    private void downloadFile(Long signId,Long docType, HttpServletResponse response) throws Exception {
        Sign sign = signMapper.selectById(signId);
        // 签署标题 也就是压缩包名称
        String title = sign.getTitle()+".zip";
        // 根据signId查询签署文档
        List<SignDocumentVO> signDocumentVOS = signDocumentMapper.selectFilesBySignID(signId,docType);
        //清空输出流
        response.reset();
        //定义输出类型
        response.setContentType("application/octet-stream");
        response.setHeader("content-disposition", "attachment;filename=" + title);
        // 打包下载
        ZipUtils.getZipFile(IOUtils.getByte(signDocumentVOS), response.getOutputStream(), response);
    }

通过Debug,我最终把错误原因锁定到了中文编码上,这里我直接把中文传到了response里面

3.png

既然发现了问题,就很好解决了,我们对中文进行编码处理再传输

全部代码奉上

    private void downloadFile(Long signId,Long docType, HttpServletResponse response) throws Exception {
        Sign sign = signMapper.selectById(signId);
        // 签署标题 也就是压缩包名称
        String title = sign.getTitle()+".zip";
        // 编译成utf-8格式
        title = URLEncoder.encode(title,"UTF-8");
        // 根据signId查询签署文档
        List<SignDocumentVO> signDocumentVOS = signDocumentMapper.selectFilesBySignID(signId,docType);
        //清空输出流
        response.reset();
        //定义输出类型
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename="+title+";"+"filename*=utf-8''"+title);
        // 打包下载
        ZipUtils.getZipFile(IOUtils.getByte(signDocumentVOS), response.getOutputStream(), response);
    }

其实主要是这几个地方,我标记出来4.png

重启服务,验证结果


解决问题

5.pngimage.png


可能导致的其他报错原因以及解决思路


1 tomcat连接超时

可以设置Tomcat的连接超时时间


具体操作为 :

1 进入tomcat中conf目录

2 打开server.xml文件

3 找到配置端口的地方,将 connectionTimeout 参数由原来默认的20000(20秒)改为60000(60秒)


如果你是SpringBoot项目就更简单了 直接在配置文件编写配置代码


# tomcat 超时连接时间
server:
  tomcat:
    connection-timeout: 60000

image.png

2 跨域问题

域问题导致。网上说要设置response的请求头属性,因为我是用ApiFox调试没有遇到跨域,不过也是一种可能

response.addHeader("Access-Contro1-A11ow-0rigin”, "*");

3 前端因素

使用ajax或者事件时,form表单提交按钮就没必要设置为submit类型,使用普通的button类型就行了,否则会出现以上错误信息


4 后端因素

个人猜测


1 后台处理时间太长了(逻辑太复杂或者死循环)

2 并发量很大

3 流没关


5 其他因素

网络问题也是不可忽视的一部分,如果你的网络波动很大或者说操作的时候断网,那么也极有可能出现这个问题


目录
打赏
0
1
0
0
1
分享
相关文章
解锁“分享文件”高效密码:探秘 Java 二叉搜索树算法
在信息爆炸的时代,文件分享至关重要。二叉搜索树(BST)以其高效的查找性能,为文件分享优化提供了新路径。本文聚焦Java环境下BST的应用,介绍其基础结构、实现示例及进阶优化。BST通过有序节点快速定位文件,结合自平衡树、多线程和权限管理,大幅提升文件分享效率与安全性。代码示例展示了文件插入与查找的基本操作,适用于大规模并发场景,确保分享过程流畅高效。掌握BST算法,助力文件分享创新发展。
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
259 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
2月前
|
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
119 34
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
40 0
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
当MySQL 8.4启动时报错“io_setup() failed with EAGAIN”时,通常是由于系统AIO资源不足所致。通过增加AIO上下文数量、调整MySQL配置、优化系统资源或升级内核版本,可以有效解决这一问题。上述解决方案详细且实用,能够帮助管理员快速定位并处理此类问题,确保数据库系统的正常运行。
136 9
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
75 3
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
56 14
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
40 13
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
1月前
|
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
113 17

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等