文档章节

springboot 获取form-data里的 file 文件小结

zcqshine
 zcqshine
发布于 2017/07/24 19:00
字数 629
阅读 595
收藏 28
点赞 2
评论 1

这两天用 springboot 和同事的 iOS 客户端上传文件对接。在客户端他使用的是 afnetworking 第三方库。我使用的是 springboot 集成的 StandardMultipartHttpServletRequest 的解析方式。 写好服务器端的接口以后,使用 postman 模拟 form-data 混合上传普通文本数据和 file 文件是没问题的。后来再 iOS 端混合上传文本和 file 的时候,发现 multiPartFile 解析不到文件。经过查看 StandardMultipartHttpServletRequest 的源文件,以及断点跟踪,发现在 form-data 解析成 part 的时候是没问题的,在遍历 part 的时候就发现问题的所在了。

下图是 postman 模拟上传时候的断点跟踪: postman模拟上传 在途中的红框里可以发现在 files 这个 part 里面的 content-dispostion 这个 key 对应的 value 里面包含filename="Jitu....."部分。而在普通的文本输入框对应的 part 部分是没这段值的。 我用 iOS 客户端进行测试的时候发现文件上传的部分是缺少这段值的.

我们再来看StandardMultipartHttpServletRequest的一部分源码:

 private static final String CONTENT_DISPOSITION = "content-disposition";
private static final String FILENAME_KEY = "filename=";
private static final String FILENAME_WITH_CHARSET_KEY = "filename*=";

private void parseRequest(HttpServletRequest request) {
	try {
		Collection<Part> parts = request.getParts();
		this.multipartParameterNames = new LinkedHashSet<String>(parts.size());
		MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size());
		for (Part part : parts) {
			String disposition = part.getHeader(CONTENT_DISPOSITION);
			String filename = extractFilename(disposition);
			if (filename == null) {
				filename = extractFilenameWithCharset(disposition);
			}
			if (filename != null) {
				files.add(part.getName(), new StandardMultipartFile(part, filename));
			} else {
				this.multipartParameterNames.add(part.getName());
			}
		}
		setMultipartFiles(files);
	}
		catch (Throwable ex) {
			throw new MultipartException("Could not parse multipart servlet request", ex);
		}
	}

private String extractFilename(String contentDisposition) {
	return extractFilename(contentDisposition, FILENAME_KEY);
}

第一个方法是解析 request 请求的, 作用是将 request 里面的form-data表单数据分类解析为普通文本输入和文件输入, 而第二个方法就是用来判断是否为文件的, 其中第二个参数值就是filename=, 如果content-dispostion的值里包含这个值, 则判断为文件, 否则就是普通文本输入. 看到这里就能明白为什么在跟 iOS 客户端联调的时候没把文件流解析成multipartFile. 这时候只需要在客户端组装form-data的时候需要加上filename=xxx这部分值.

© 著作权归作者所有

共有 人打赏支持
zcqshine
粉丝 6
博文 39
码字总数 12795
作品 0
深圳
高级程序员
加载中

评论(1)

七仔谁用了
七仔谁用了
:heavy_exclamation_mark:
springboot打成jar包后配置外部资源映射成静态资源

很多的项目都要上传图片那些,然后通过打包jar包或者war包发布到服务器上,我们不可能把上传图片的文件夹放在jar包或者war包里面,那样会越来越大。所以有了下面的配置,其他框架都好说可以把...

duangecho ⋅ 05/09 ⋅ 0

恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年 ⋅ 04/19 ⋅ 0

学习 Spring Boot 知识看这一篇就够了

从2016年因为工作原因开始研究 Spring Boot ,先后写了很多关于 Spring Boot 的文章,发表在技术社区、我的博客和我的公号内。粗略的统计了一下总共的文章加起来大概有六十多篇了,其中一部分...

ityouknow ⋅ 05/28 ⋅ 0

SpringBoot 2.0 系列001 -- 入门介绍以及相关概念

SpringBoot 2.0 系列001 -- 入门介绍以及相关概念 什么是SpringBoot? 项目地址:http://projects.spring.io/spring-boot/ SpringBoot介绍 Spring Boot使开发独立的,产品级别的基于Spring的...

路上有你0314 ⋅ 05/10 ⋅ 0

springboot2输出metrics到influxdb

序 本文主要研究一下如何将springboot2的metrics输出到influxdb maven 配置 influx 启动之后创建数据库 命令行创建 rest接口创建 返回 或者直接配置文件指定auto-create-db=true,就无需额外...

go4it ⋅ 前天 ⋅ 0

使用IntelliJ Idea新建SpringBoot项目

简单给大家介绍一下我来创建SpringBoot项目使用的工具,本人使用IntelliJ Idea来创建项目,利用其中的Spring Initializr工具来快速创建项目。 步骤如下: 菜单栏中选择File--New--Project,出...

dalaoyang ⋅ 03/11 ⋅ 0

SpringBoot2.x整合MyBatis

首先在IDEA中创建一个SpringBoot工程: 选择一些基本的包: 完成创建: 工程创建成功后,补充pom.xml文件中的依赖,完整的依赖如下: 编辑配置文件完成后,打开SpringBoot的启动类,加上@Ma...

ZeroOne01 ⋅ 06/12 ⋅ 0

SpringBoot 整合 oauth2(四)实现 token 持久化

为什么需要给token做持久化,试想如果存储token的服务器宕机后,用户信息也会伴随着失效,用户需要重新登陆来获取token,难免降低了用户体验,所以我们需要像处理session分布式一样,将token...

FantJ ⋅ 05/15 ⋅ 0

第一章:Maven环境下如何配置QueryDSL环境

QueryDSL是一个通用的查询框架,框架的核心原则是创建安全类型的查询,开始QueryDSL仅支持Hibernate(HQL),在不断开源人士加入QueryDSL团队后,陆续发布了针对JPA,JDO,JDBC,Lucene,Hib...

恒宇少年 ⋅ 2017/07/01 ⋅ 0

SpringBoot学习【简】

这里有一个不错的专栏,推荐一下 SpringBoot 教程 SpringBoot(四):SpringBoot整合JdbcTemplate SpringBoot(五):SpringBoot整合MyBatis 尤其这两文...

anlve ⋅ 05/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 46分钟前 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

马氏距离与欧氏距离

马氏距离 马氏距离也可以定义为两个服从同一分布并且其协方差矩阵为Σ的随机变量之间的差异程度。 如果协方差矩阵为单位矩阵,那么马氏距离就简化为欧氏距离,如果协方差矩阵为对角阵,则其也...

漫步当下 ⋅ 昨天 ⋅ 0

聊聊spring cloud的RequestRateLimiterGatewayFilter

序 本文主要研究一下spring cloud的RequestRateLimiterGatewayFilter GatewayAutoConfiguration @Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMi......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部