Ajax请求下载文件的解决方案

写这个博客之前我并不清楚 ajax请求是下载不了文件的 😅 这段时间在写一个自己的项目,用到了ajax下载文件,请求到了controller层并返回文件下载成功 但是浏览器就是没有反应,找了很多资料以及在网上搜了很多文章,但找到的文章的着重点 还是在controller层对文件的处理上,最后为了验证controller是没有问题的,我就在jsp中直接写了一个form表单提交,可想而知的效果是文件顺利下载下来了,所以反过来想应该是ajax请求的问题,因为我的业务场景是 当用户点击下载按钮时,控制层接收到请求后 先去查询数据,然后拼装成一个Excel文件,把文件上传到服务器,我的想法是由于中间的流程或者说逻辑有些复杂可能会出现一些不可预料的异常 需要反馈给用户,所以这就变成了不仅是下载文件这么简单,如果直接用form表单提交 我就无法展示系统的错误信息。

这中间也发生了这样的异常 java.lang.IllegalStateException: getOutputStream() has already been called for this response

遇到这样报错的原因是:controller层返回了一个jsp,但是这个请求是 下载文件

返回一个页面时web容器生成的servlet代码中有out.write(“”) 字符型输出流,但是在写文件到浏览器时 我用response.getOutputStream() 字节型输出流,所以导致了这个冲突

其实这个异常和本次我写这个博客的目的无关 只是我在解决这个业务场景时 原本想到的解决方案但出现了异常也就pass(淘汰)了我这个想法,所以为了让自己以后不会出现相同的问题就随口一说

应对这个场景正确的解决方案:

前端jsp://一个输入框 两个按钮 一个按钮是计算 一个按钮是下载

请输入一个标识符:

js:// 计算的忽略 只看下载

$(function(){

// 监听download按钮的点击事件 相当于document.getElementById(“button-down”)

$(“#button-down”).click(function(){

// 获取两个标签之间的值用 .text(); 标签内的value值 用 .val();

var flagNum = $(“#flagnum”).val();

//发送ajax请求

$.ajax({

url: “export”,

type: “post”,

data: {“flagNum”: flagNum},

success: function(data){

//这一块我在后端封装了一个响应对象 {message:{success:true, returnObject{这里是一个map}, msg:”响应信息”, code:响应状态码, name:响应名称},data:{这里是一个map}}

var message = data.message;

if(message.success){

//调用如下用于拼接form表单请求的download方法

// url 是请求的路径 name就是input表单中的name value是export这个请求获取的服务器中的文件地址 method 是请求方法 post / get

download(“url”,”name”,”value”,”method”);

}else {

alert(这里输出一下错误信息);

error: funciton(e){

alert(接口调用失败);

});

});

});

function download(url,name,value,method){

//拼接一个form表单 里面有input标签 追加到标签中 提交后删除这个form表单;

$().appendTo(“body”).submit().remove();

controller 层:

@RequestMapper(“download”)

public void download(HttpServletResponse response, @Param(“filePath”) String filePath){

FileDowloadUtil.windowDownload(response, filePath);

文件下载的工具类 FileDowloadUtil:

public static void windowDownload(HttpServletResponse response, String filePath){

// 判断文件地址是否为空

if(filePath.isEmpty()){

return;

//获取文件名

//String fileName = filePath.subString(filePath.lastIndexOf(“.”) +1);

File file = new File(filePath);

if(file == null){

return;

String fileName = file.getName();

//设置响应头,控制浏览器下载该文件 设置下载的文件为excel  application/vnd.ms-excel  下载别的文件是  百度下 content-type 对应的文件类型即可
try {    fileName = URLEncoder.encode(fileName,"UTF-8");} catch (UnsupportedEncodingException e) {    e.printStackTrace();}response.setHeader("content-type","application/vnd.ms-excel");response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment; filename=" + fileName);byte[] bytes = new byte[1024];InputStream is = null;OutputStream out = null;try {    is = new FileInputStream(file);    out = response.getOutputStream();    int len = 0;    while ((len = is.read(bytes)) != -1){        out.write(bytes,0,len);        out.flush();    }} catch (UnsupportedEncodingException e) {    log.error("异常:"+e.getMessage());} catch (IOException e){    log.error("异常:"+e.getMessage());} finally {    if (out != null){        try {            out.close();        } catch (IOException e) {            log.error("异常:"+e.getMessage());        }    }    if (is != null){        try {            is.close();        } catch (IOException e) {            log.error("异常:"+e.getMessage());        }    }}

如上就是解决方案的全部代码;

Original: https://www.cnblogs.com/ganguixu/p/14879497.html
Author: 干桂旭
Title: Ajax请求下载文件的解决方案

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/591894/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 当mysql表从压缩表变成普通表会发生什么

    本文章做了把mysql表从压缩表过渡到普通表的实验过程,看看压缩表变成普通表会发生什么?本文针对mysql5.7和mysql8分别进行了实验。 1、什么是表压缩 在介绍压缩表变成普…

    数据库 2023年6月16日
    077
  • 线程池:ThreadPoolExcutor源码阅读

    ThreadPoolExcutor源码流程图:(图片较大,下载再看比较方便) 线程池里的二进制奥秘 前言: 线程池的五种状态state (RUNNING 、SHUTDOWN 、ST…

    数据库 2023年6月16日
    0118
  • 就这么一个简单的校验,80%的程序员却做不到,更不理解!

    在学生管理系统里,其中会有学生信息采集的功能。程序结构不外乎下面的分层实现方式。 开发出来这个功能,我觉得大家都易如反掌了。 当然易如反掌。 OK,我要说的是数据校验,以最简单的非…

    数据库 2023年6月9日
    084
  • 模板语法之传值取值

    模板语法之传值 变量相关使用:{{}}逻辑语法相关:{% %} 后端传值部分: def index(request): # 模版&amp…

    数据库 2023年6月14日
    072
  • 史上最全Mysql规范

    1 整体规约 1)【强制】数据库所有对象必须要有注释,包括:表、字段、索引等,并且要保持最新; 1)【强制】默认使用utf8字符集,无乱码风险,除一些需要存储特殊符号的字段,可以采…

    数据库 2023年6月14日
    074
  • Jmeter性能测试场景的创建和运行

    目录 性能测试场景的分析 项目背景 Jmeter指标 性能测试场景的设计以及准备 * 性能测试的总结 性能测试场景的分析 项目背景 ​ 实际工作中,我们拿到一个项目一般来说都会是项…

    数据库 2023年6月6日
    093
  • 百度我为你伤心

    9月9日 我写了一篇文章,原名:事务方块,后改名:事务的本质和死锁的原理 9月10日23点 我突然发现,这个原创文章被转载盗贴,可气的是都没有记录原创地址 早上我查了一下搜索引擎排…

    数据库 2023年6月9日
    096
  • myrocks复制中断问题排查

    mysql可以支持多种不同的存储引擎,innodb由于其高效的读写性能,并且支持事务特性,使得它成为mysql存储引擎的代名词,使用非常广泛。随着SSD逐渐普及,硬件存储成本越来越…

    数据库 2023年6月9日
    0107
  • SMBMS(超市订单管理系统)项目从零开始搭建

    如果需要完整的系统可以加我qq:1842329236 一、搭建一个maven web项目 新建一个maven,并且使用模板 maven的详细创建,及配置请看这篇文章https://…

    数据库 2023年6月16日
    080
  • MySQL执行一条查询语句的过程

    查询缓存 在解析一个查询语句之前,如果查询缓存时打开的,那么 MySQL 会优先检查这个查询是否命中查询缓存中的数据。这个检查时通过一个对大小写敏感的哈希查找实现的。查询和缓存中的…

    数据库 2023年5月24日
    0108
  • Linux常用指令

    Linux常用指令 到达底部 运行级别有以下几种 0级:关机 1级:单用户 (找回密码) 2级: 多用户没有网络服务 3级: 多用户有网络服务 4级: 系统未使用保留给用户 5级:…

    数据库 2023年6月16日
    089
  • 读取资源文件的几种常用方法

    资源文件的读取方法: 本地读取资源文件 undefined2. 服务器(Tomcat)通过ServletContext获取: ServletContext servletConte…

    数据库 2023年6月16日
    094
  • 面试必问之 ConcurrentHashMap 线程安全的具体实现方式

    作者:炸鸡可乐原文出处:www.pzblog.cn 一、摘要 在之前的集合文章中,我们了解到 HashMap 在多线程环境下操作可能会导致程序死循环的线上故障! 既然在多线程环境下…

    数据库 2023年6月14日
    0100
  • 【黄啊码】使用think-queue产生大量日志文件怎么办?

    有时候某些原因程序出错,会有大量日志生成,最好调整下日志,单独出来。在配置文件config/queue.php开头添加: use think\facade\Log;Log::ini…

    数据库 2023年6月16日
    092
  • Kmp算法

    算法流程: kmp_search(char[] text,char[] pattern) 构建前缀表 prefix[0]默认&#…

    数据库 2023年6月11日
    0119
  • 9、手写一个starter

    一、starte详解: 1、starter场景启动器: SpringBoot-starter是一个集成接合器,主要完成两件事: (1)、引入模块所需的相关jar包 (2)、自动配置…

    数据库 2023年6月6日
    080
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球