Skip to content

Support Multiple Files for One Form Field in multipart/form-data #2872

Closed
@dschulten

Description

@dschulten

Affects Version(s): 5.1.3


Bug

The multipart/form-data RFC states:

multiple files MUST be sent
by supplying each file in a separate part but all with the same
"name" parameter

However, when I send a multipart message with three parts named data, only one makes it into the message.

Sample request (with Intellij's http client)
### Send a form with the text and file fields
POST http://localhost:8091/conversion
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data.tiff"
Content-Type: image/tiff

< ../resources/inputSamples/data.tiff
--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data2.tiff"
Content-Type: image/tiff

< ../resources/inputSamples/data2.tiff
--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data3.tiff"
Content-Type: image/tiff

< ../resources/inputSamples/data3.tiff
--WebAppBoundary--

The reason is that MultipartAwareFormHttpMessageConverter#readMultipart uses multipartRequest.getFileMap()to access the files:

private MultiValueMap<String, ?> readMultipart(MultipartHttpInputMessage multipartRequest) throws IOException {
	MultiValueMap<String, Object> resultMap = new LinkedMultiValueMap<String, Object>();
	Map<?, ?> parameterMap = multipartRequest.getParameterMap();
	for (Entry<?, ?> entry : parameterMap.entrySet()) {
		resultMap.add((String) entry.getKey(), entry.getValue());
	}
	for (Map.Entry<String, MultipartFile> entry : multipartRequest
            .getFileMap().entrySet()) { //                               <== problematic
		MultipartFile multipartFile = entry.getValue();
		if (multipartFile.isEmpty()) {
			continue;
		}
		resultMap.add(entry.getKey(), this.multipartFileReader.readMultipartFile(multipartFile));
	}
	return resultMap;
}

which ultimately comes to AbstractMutlipartHttpServletRequest:

public Map<String, MultipartFile> getFileMap() {
    return getMultipartFiles().toSingleValueMap();
}

Here it loses all but the first files.

Possible solution: Use MultipartHttpInputMessage#getMultiFileMap instead of getFileMap. I suggest to treat this as a bug because it really seems that getFileMap was used inadvertently.

Workaround: use different names for all multipart files (pretty ugly, though).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions