解决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 其他因素

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


相关文章
|
4天前
|
监控 安全 Java
Java与物联网:连接与控制设备
Java与物联网:连接与控制设备
16 0
|
2天前
|
前端开发 Java 应用服务中间件
【异常解决】java程序连接MinIO报错The request signature we calculated does not match the signature you provided.
【异常解决】java程序连接MinIO报错The request signature we calculated does not match the signature you provided.
|
2天前
|
Java 开发者
Java一分钟之-Java IO流:文件读写基础
【5月更文挑战第10天】本文介绍了Java IO流在文件读写中的应用,包括`FileInputStream`和`FileOutputStream`用于字节流操作,`BufferedReader`和`PrintWriter`用于字符流。通过代码示例展示了如何读取和写入文件,强调了常见问题如未关闭流、文件路径、编码、权限和异常处理,并提供了追加写入与读取的示例。理解这些基础知识和注意事项能帮助开发者编写更可靠的程序。
12 0
|
2天前
|
SQL Java 关系型数据库
【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库
【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库
|
3天前
|
Java
JDK环境下利用记事本对java文件进行运行编译
JDK环境下利用记事本对java文件进行运行编译
11 0
|
4天前
|
SQL Java 数据库连接
Java数据库编程实践:连接与操作数据库
Java数据库编程实践:连接与操作数据库
9 0
|
5天前
|
Arthas 安全 Java
java服务报错 FileNotFoundException:打开的文件过多
java服务报错 FileNotFoundException:打开的文件过多
15 0
|
1月前
|
存储 缓存 安全
Java 中 IO 流、File文件
Java 中 IO 流、File文件
|
17天前
|
Java Unix Windows
|
7天前
|
存储 缓存 Java
Java IO 流详解
Java IO 流详解
16 1