解决springboot接受buffer文件为null(从picgo上传buffer看springmvc处理过程)

news/2025/2/1 10:03:00/

1. 前言:

picgo插件的简单开发

上篇文章我们简单写了picgo上传插件,但是当我们测试的时候,发现问题了,后端MultipartFile file接受到的文件为null。
在这里插入图片描述

2. 排查问题:

参考的文档

  1. picgo api列表
  2. 关于multipart form-data中filename的问题

2.1. 我们先排查前端

const handle = async (ctx) => {let userConfig = ctx.getConfig('picBed.haowan-uploader')if (!userConfig) {throw new Error('Can\'t find uploader config')}const Url = userConfig.Urlconst Token = userConfig.Tokenconst imgList = ctx.outputfor (let i in imgList) {let image = imgList[i].bufferif (!image && imgList[i].base64Image) {image = Buffer.from(imgList[i].base64Image, 'base64')}const postConfig = postOptions(Url, Token, imgList[i].fileName, image)let body = await ctx.request(postConfig)body = JSON.parse(body)return ctx
}const postOptions = (Url, Token, fileName, image) => {return {method: 'POST',url: Url + `/api/picgo/upload`,headers: {"contentType": 'multipart/form-data','Authorization':  Token,'User-Agent': 'PicGo'},formData: {file : image,fileName}}
} 
  1. 我首先考虑的是我api使用问题

在这里插入图片描述
🌴我使用的是pico的.request方法,作者描述是通过使用axios实现的。
在这里插入图片描述
在这里插入图片描述
🌴使用formdata属性配置表单数据是没有问题的,可以看到picgo的底层通过读取formdata属性,把你所配置的数据读取配置到axios发送的data数据中。是axios的常用实现。

😄 由于我们使用的是picgo gui,所以控制台无法方便的使用,所以我们下面从后端排查数据是否发送
在这里插入图片描述

2.2. 排查后端

  1. 在参数接收这里点上debug
    在这里插入图片描述
    🌴我们可以看出并非没有接受文件,只是在最后并没有转换成文件。
    在这里插入图片描述

  2. 查看body流读取的源码
    在这里插入图片描述

Collection<Part> parts = request.getParts();this.multipartParameterNames = new LinkedHashSet(parts.size());MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap(parts.size());Iterator var4 = parts.iterator();while(var4.hasNext()) {Part part = (Part)var4.next();String headerValue = part.getHeader("Content-Disposition");ContentDisposition disposition = ContentDisposition.parse(headerValue);String filename = disposition.getFilename();if (filename != null) {if (filename.startsWith("=?") && filename.endsWith("?=")) {filename = StandardMultipartHttpServletRequest.MimeDelegate.decode(filename);}files.add(part.getName(), new StandardMultipartFile(part, filename));} else {this.multipartParameterNames.add(part.getName());}}this.setMultipartFiles(files);

在这里插入图片描述

String filename = disposition.getFilename();,由于这里文件名为空,以致于mvc根本不处理文件流。

那么解决方案就显而易见,给添加上文件流就行。

3. 解决方案(添加文件名):

  1. https://www.rfc-editor.org/rfc/rfc1867 (formdata上传文件描述)

在这里插入图片描述
2. formdata buffer流添加文件名

在这里插入图片描述

formData: {file: {value: image,options: {filename: fileName}}

可以在formdata中可选属性options添加文件名的选项。就可以成功读取了。
在这里插入图片描述


http://www.ppmy.cn/news/1212747.html

相关文章

微信支付平台C#SDK_微信支付.net SDK

一、微信支付平台C# SDK V3 https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/docs/WechatTenpayV3 接口对应整理&#xff1a; https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/docs/WechatTenpayV3/Basic_Mod…

SpringBoot | @EnableAutoConfiguration注解介绍

介绍 EnableAutoConfiguration注解用于SpringBoot自动配置。该注解内部使用Import(AutoConfigurationImportSelector.class)加载配置类。 加载原理 使用Import(AutoConfigurationImportSelector.class)加载配置类&#xff0c;配置文件对应的位置&#xff1a;META-INF/spring…

【多线程】

文章目录 概念一、线程的生命周期图二、线程的创建方式一方式二线程API线程优先级sleep阻塞守护线程多线程并发安全问题 总结 概念 线程:一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。多线程:多个单一顺序执行的流程并发运行。造成"感官上…

React中创建和组织组件以及如何在组件之间传递数据和管理状态

import React, { useState } from react;// 子组件 const ChildComponent ({ name }) > {return (<div><h2>Hello, {name}!</h2></div>); }// 父组件 const ParentComponent () > {const [name, setName] useState(John Doe);const handleCha…

矩阵理论--矩阵分解

矩阵理论–矩阵分解 矩阵的三角分解、谱分解、最大秩分解、奇异值分解的操作步骤&#xff0c;以及相关说明。 1、QR分解 &#xff08;1&#xff09;非奇异方阵 方阵&#xff08;非奇异&#xff09;&#xff1a;将方阵分解成酉矩阵左乘正线上三角&#xff0c;或者酉矩阵右乘…

Vue I18n 国际化插件,从安装到使用最全篇

目录 一、介绍 二、插件基本思路 三、插件版本适用框架 四、Vue3 中使用 1. 安装插件 vue-i18n 2. 定义和组合语言包 3. 引入插件并创建 i18n 实例 4. 挂载实例对象 main.js 文件中的完整代码&#xff1a; 在组件中使用&#xff1a; 四、动态切换语言 1. 获取浏览器…

数据管理系统-week1-数据库设计

文章目录 一、数据库设计过程二、数据库域三、数据库模式四、对象建模参考文献 一、数据库设计过程 数据库设计的简化过程包括以下阶段&#xff1a; -概念建模 概念建模将数据库域的规范转换为概念模式。 -逻辑设计 逻辑设计将概念模式转换为逻辑模式&#xff0c;例如关系表的…

【Redis】String字符串类型

上一篇&#xff1a;Redis-key的使用 https://blog.csdn.net/m0_67930426/article/details/134361821?spm1001 .2014.3001.5501 目录 appen (附加&#xff09; strlen(获取字符串的长度&#xff09; incr decr getRange(获取字符串&#xff09; setRange&#xff08;替…