Add all non-file parts as request parameters
Closes gh-26400
This commit is contained in:
parent
4779323d33
commit
584dabbb39
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.test.web.servlet.request;
|
package org.springframework.test.web.servlet.request;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
@ -38,7 +39,6 @@ import org.springframework.util.Assert;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default builder for {@link MockMultipartHttpServletRequest}.
|
* Default builder for {@link MockMultipartHttpServletRequest}.
|
||||||
|
|
@ -144,47 +144,40 @@ public class MockMultipartHttpServletRequestBuilder extends MockHttpServletReque
|
||||||
@Override
|
@Override
|
||||||
protected final MockHttpServletRequest createServletRequest(ServletContext servletContext) {
|
protected final MockHttpServletRequest createServletRequest(ServletContext servletContext) {
|
||||||
MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(servletContext);
|
MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(servletContext);
|
||||||
|
Charset defaultCharset = (request.getCharacterEncoding() != null ?
|
||||||
|
Charset.forName(request.getCharacterEncoding()) : StandardCharsets.UTF_8);
|
||||||
|
|
||||||
this.files.forEach(request::addFile);
|
this.files.forEach(request::addFile);
|
||||||
this.parts.values().stream().flatMap(Collection::stream).forEach(part -> {
|
this.parts.values().stream().flatMap(Collection::stream).forEach(part -> {
|
||||||
request.addPart(part);
|
request.addPart(part);
|
||||||
try {
|
try {
|
||||||
MultipartFile file = asMultipartFile(part);
|
String name = part.getName();
|
||||||
if (file != null) {
|
String filename = part.getSubmittedFileName();
|
||||||
request.addFile(file);
|
InputStream is = part.getInputStream();
|
||||||
return;
|
if (filename != null) {
|
||||||
|
request.addFile(new MockMultipartFile(name, filename, part.getContentType(), is));
|
||||||
}
|
}
|
||||||
String value = toParameterValue(part);
|
else {
|
||||||
if (value != null) {
|
InputStreamReader reader = new InputStreamReader(is, getCharsetOrDefault(part, defaultCharset));
|
||||||
request.addParameter(part.getName(), toParameterValue(part));
|
String value = FileCopyUtils.copyToString(reader);
|
||||||
|
request.addParameter(part.getName(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new IllegalStateException("Failed to read content for part " + part.getName(), ex);
|
throw new IllegalStateException("Failed to read content for part " + part.getName(), ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private Charset getCharsetOrDefault(Part part, Charset defaultCharset) {
|
||||||
private MultipartFile asMultipartFile(Part part) throws IOException {
|
if (part.getContentType() != null) {
|
||||||
String name = part.getName();
|
MediaType mediaType = MediaType.parseMediaType(part.getContentType());
|
||||||
String filename = part.getSubmittedFileName();
|
if (mediaType.getCharset() != null) {
|
||||||
if (filename != null) {
|
return mediaType.getCharset();
|
||||||
return new MockMultipartFile(name, filename, part.getContentType(), part.getInputStream());
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return defaultCharset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String toParameterValue(Part part) throws IOException {
|
|
||||||
String rawType = part.getContentType();
|
|
||||||
MediaType mediaType = (rawType != null ? MediaType.parseMediaType(rawType) : MediaType.TEXT_PLAIN);
|
|
||||||
if (!mediaType.isCompatibleWith(MediaType.TEXT_PLAIN)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Charset charset = (mediaType.getCharset() != null ? mediaType.getCharset() : StandardCharsets.UTF_8);
|
|
||||||
InputStreamReader reader = new InputStreamReader(part.getInputStream(), charset);
|
|
||||||
return FileCopyUtils.copyToString(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -50,7 +50,7 @@ public class MockMultipartHttpServletRequestBuilderTests {
|
||||||
assertThat(mockRequest.getParts()).extracting(Part::getName).containsExactly("name");
|
assertThat(mockRequest.getParts()).extracting(Part::getName).containsExactly("name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // gh-26261
|
@Test // gh-26261, gh-26400
|
||||||
void addFileWithoutFilename() throws Exception {
|
void addFileWithoutFilename() throws Exception {
|
||||||
MockPart jsonPart = new MockPart("data", "{\"node\":\"node\"}".getBytes(UTF_8));
|
MockPart jsonPart = new MockPart("data", "{\"node\":\"node\"}".getBytes(UTF_8));
|
||||||
jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
@ -62,7 +62,8 @@ public class MockMultipartHttpServletRequestBuilderTests {
|
||||||
.buildRequest(new MockServletContext());
|
.buildRequest(new MockServletContext());
|
||||||
|
|
||||||
assertThat(mockRequest.getFileMap()).containsOnlyKeys("file");
|
assertThat(mockRequest.getFileMap()).containsOnlyKeys("file");
|
||||||
assertThat(mockRequest.getParameterMap()).isEmpty();
|
assertThat(mockRequest.getParameterMap()).hasSize(1);
|
||||||
|
assertThat(mockRequest.getParameter("data")).isEqualTo("{\"node\":\"node\"}");
|
||||||
assertThat(mockRequest.getParts()).extracting(Part::getName).containsExactly("data");
|
assertThat(mockRequest.getParts()).extracting(Part::getName).containsExactly("data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue