前端将file文件传给后台,后台将文件传给前台(包含上传下载)

前端将file文件传给后台,后台将文件传给前台(包含上传下载)

在开发过程中,经常会遇见对文件的处理。

例如:在上传、下载文件时,需要在前端选完文件传到后台传到服务器;或者文件从后台,经过特定需求的处理在返回给前台。

中间处理过程各种各样,但有两个过程是固定的

  • 前端传给后台
  • 后台返回给前端

经常用到的上传就是对应第一步,下载对应第二部。会在文章最后总结。

下面是示例代码

  1. 前台传给后台

    界面采用el-upload组件,在选择文件时,将文件传给后台

    vue 复制代码
    <el-upload class="upload-demo" ref="upload" action="#" :on-change="changeFile" :file-list="fileList" :auto-upload="false" :limit="1">
      <el-button slot="trigger" size="small" type="primary">选取文档</el-button>
    </el-upload>

    选择完文件会走changeFile(file)方法,其中默认入参为选中的文件,如下图,真正的文件类型是File类型的raw变量

    不能直接将File类型变量传输,要把File文件转成FormData类型,通过axios发送请求

    用的组件不同可能返回的类型、变量名不一样,但最后要获取到File文件类型,通过FormData()进行转换传向后台。

    需要配置的参数:

    • method:post
    • url:自己的接口地址
    • data:请求前转换类型的参数
    • headers:credentials: 'same-origin'
    • responseType:'blob' //用于接收后台返回的文件所需类型
    javascript 复制代码
    //el-upload文件上传事件
    changeFile(file) {
      let formData = new FormData()
      formData.append('file', file.raw)// 传文件
      axios({
         method: 'post',
         url: url, //此处为往后台发送请求的地址
         data: formData,
         headers: {
           // "Content-Type": "multipart/form-data" 
           credentials: 'same-origin'
         },
         timeout: 20000,
          //设置返回接受类型为blob
         responseType: 'blob'
       }).then(res => {
          //返回值转成Blob类型
         let blob = new Blob([res.data])
       });
    },

    后端用MultipartFile类接收,并且获取HttpServletRequestHttpServletResponse参数,看下controller层的代码

    java 复制代码
    @PostMapping("transferFile")
    public void transferFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws Exception {
        deptService.transferFile(file, request, response);
    }

    可以看到成功获取到在前台选择的文件

    那后台怎么返回给前台呢

  2. 后台将文件传给前台

    接着上面,看下service实现类的代码

    java 复制代码
    @Override
    public void transferFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream inputStream = file.getInputStream();
        String fileName = file.getOriginalFilename();
        /**
        *	此处可以对文件输入流按照需求进行【自定义操作】
        *	操作完后也要返回一个字节数组
        */
        byte[] bytes = new byte[1024];
        inputStream.read(bytes);
        try {
            response.setCharacterEncoding("UTF-8");
            //设置ContentType字段告知浏览器返回内容类型
            response.setContentType("application/octet-stream");
            //设置Header字段
            //下面这行代码必须加,否则前端获取不到Content-Disposition字段,即无法获取文件名
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ServletOutputStream out = response.getOutputStream();
            out.write(bytes);
            out.flush();
            out.close();
        } catch (Exception e) {
        } finally {
            inputStream.close();
        }
    }

    看上面代码,通过file.getInputStream()方法获取到文件的输入流,在调用read()方法,将其读到字节数组中,response.setContentType("application/octet-stream")设置返回值类型。通过response.getOutputStream()方法,获取返回的输出流,调用write将刚才读到处理完的字节数组写入,最后将流关闭。

    中间部分可以对流进行自定义操作,操作完成后返回字节数组,写到response的输出流中即可

    例如该项目中会将doc文件的流转成docx格式的流,感兴趣的可以看之后的文章。

    接口执行完成,前端将返回值转成Blob类型,且发送请求时已经设置了responseType为'blob'。如下图两处关键点。

到此文件前后台之间的传输过程就全部结束。

此处介绍的是个完整的过程,对于上传和下载其实是两步拆开单独对应。

  • 上传

    完整的对应第一步骤:选择文件->传递给后台->后台转成流调用第三方接口上传到文件服务器

  • 下载

    通常从后台调用第三方接口获取文件,一般会以流的形式返回,此时为输入流,然后拿到response的输出流,写入。

    获取远程文件输入流->写入响应参数的输出流

    java 复制代码
    ServletOutputStream out = response.getOutputStream();
    out.write(bytes);

    com.google.api.client.util下有个工具类可以直接实现流之间的复制,省去多样步骤

    IOUtils.copy(inputStream, response.getOutputStream());

相关推荐
城管不管12 分钟前
重生——第十次面试之开源中国一面挂
java·linux·开发语言·算法·面试·职场和发展·开源
Java小白笔记15 分钟前
Windows系统免软件命令激活
java·网络·人工智能·windows·ai·ai编程
爱敲键盘的猴子24 分钟前
深入理解 Java HashMap
java·hashmap
霸道流氓气质25 分钟前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
前端小卡拉36 分钟前
用了大半年 AI 编程工具,我才搞懂 Skill 到底是什么
前端·javascript
天涯醉青楼37 分钟前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
郭邯42 分钟前
用 Intl.DateTimeFormat 手写一个时区转换器,顺便聊聊我和 AI 结对编程的日常
前端·javascript
步行cgn1 小时前
MyBatis 高级映射与延迟加载完全指南
java·tomcat·mybatis
thefool1122661 小时前
从中序与后序遍历序列构造二叉树
java
吴声子夜歌1 小时前
Java面试题——JVM(二)
java·开发语言·jvm