MockHttpServletRequestBuilder parses form data
Spring MVC Test now parses application/x-www-form-urlencoded request content and populates request parameters from it. This can be useful when running client-side tests against a MockMvc via MockMvcClientHttpRequestFactory. Issue: SPR-13733
This commit is contained in:
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package org.springframework.test.web.servlet.request;
|
package org.springframework.test.web.servlet.request;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
@@ -33,8 +36,10 @@ import javax.servlet.http.Cookie;
|
|||||||
import org.springframework.beans.Mergeable;
|
import org.springframework.beans.Mergeable;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpInputMessage;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.mock.web.MockHttpSession;
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
@@ -603,24 +608,10 @@ public class MockHttpServletRequestBuilder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (this.url.getRawQuery() != null) {
|
||||||
if (this.url.getRawQuery() != null) {
|
request.setQueryString(this.url.getRawQuery());
|
||||||
request.setQueryString(this.url.getRawQuery());
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiValueMap<String, String> queryParams =
|
|
||||||
UriComponentsBuilder.fromUri(this.url).build().getQueryParams();
|
|
||||||
|
|
||||||
for (Entry<String, List<String>> entry : queryParams.entrySet()) {
|
|
||||||
for (String value : entry.getValue()) {
|
|
||||||
value = (value != null) ? UriUtils.decode(value, "UTF-8") : null;
|
|
||||||
request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException ex) {
|
|
||||||
// shouldn't happen
|
|
||||||
}
|
}
|
||||||
|
addRequestParams(request, UriComponentsBuilder.fromUri(this.url).build().getQueryParams());
|
||||||
|
|
||||||
for (String name : this.parameters.keySet()) {
|
for (String name : this.parameters.keySet()) {
|
||||||
for (String value : this.parameters.get(name)) {
|
for (String value : this.parameters.get(name)) {
|
||||||
@@ -632,6 +623,13 @@ public class MockHttpServletRequestBuilder
|
|||||||
request.setContent(this.content);
|
request.setContent(this.content);
|
||||||
request.setCharacterEncoding(this.characterEncoding);
|
request.setCharacterEncoding(this.characterEncoding);
|
||||||
|
|
||||||
|
if (this.content != null && this.contentType != null) {
|
||||||
|
MediaType mediaType = MediaType.parseMediaType(this.contentType);
|
||||||
|
if (MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType)) {
|
||||||
|
addRequestParams(request, parseFormData(mediaType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!ObjectUtils.isEmpty(this.cookies)) {
|
if (!ObjectUtils.isEmpty(this.cookies)) {
|
||||||
request.setCookies(this.cookies.toArray(new Cookie[this.cookies.size()]));
|
request.setCookies(this.cookies.toArray(new Cookie[this.cookies.size()]));
|
||||||
}
|
}
|
||||||
@@ -695,6 +693,43 @@ public class MockHttpServletRequestBuilder
|
|||||||
request.setPathInfo(this.pathInfo);
|
request.setPathInfo(this.pathInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addRequestParams(MockHttpServletRequest request, MultiValueMap<String, String> map) {
|
||||||
|
try {
|
||||||
|
for (Entry<String, List<String>> entry : map.entrySet()) {
|
||||||
|
for (String value : entry.getValue()) {
|
||||||
|
value = (value != null) ? UriUtils.decode(value, "UTF-8") : null;
|
||||||
|
request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException ex) {
|
||||||
|
// shouldn't happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MultiValueMap<String, String> parseFormData(final MediaType mediaType) {
|
||||||
|
MultiValueMap<String, String> map;HttpInputMessage message = new HttpInputMessage() {
|
||||||
|
@Override
|
||||||
|
public InputStream getBody() throws IOException {
|
||||||
|
return new ByteArrayInputStream(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHeaders getHeaders() {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(mediaType);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
map = new FormHttpMessageConverter().read(null, message);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new IllegalStateException("Failed to parse form data in request body: ", ex);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
private FlashMapManager getFlashMapManager(MockHttpServletRequest request) {
|
private FlashMapManager getFlashMapManager(MockHttpServletRequest request) {
|
||||||
FlashMapManager flashMapManager = null;
|
FlashMapManager flashMapManager = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.springframework.test.web.servlet.request;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -272,6 +273,20 @@ public class MockHttpServletRequestBuilderTests {
|
|||||||
assertArrayEquals(new String[] {"bar", "baz"}, request.getParameterMap().get("foo"));
|
assertArrayEquals(new String[] {"bar", "baz"}, request.getParameterMap().get("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestParameterFromRequestBodyFormData() throws Exception {
|
||||||
|
String contentType = "application/x-www-form-urlencoded;charset=UTF-8";
|
||||||
|
String body = "name+1=value+1&name+2=value+A&name+2=value+B&name+3";
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequestBuilder(HttpMethod.POST, "/foo")
|
||||||
|
.contentType(contentType).content(body.getBytes(Charset.forName("UTF-8")))
|
||||||
|
.buildRequest(this.servletContext);
|
||||||
|
|
||||||
|
assertArrayEquals(new String[] {"value 1"}, request.getParameterMap().get("name 1"));
|
||||||
|
assertArrayEquals(new String[] {"value A", "value B"}, request.getParameterMap().get("name 2"));
|
||||||
|
assertArrayEquals(new String[] {null}, request.getParameterMap().get("name 3"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void acceptHeader() {
|
public void acceptHeader() {
|
||||||
this.builder.accept(MediaType.TEXT_HTML, MediaType.APPLICATION_XML);
|
this.builder.accept(MediaType.TEXT_HTML, MediaType.APPLICATION_XML);
|
||||||
|
|||||||
@@ -672,5 +672,6 @@ Spring 4.3 also improves the caching abstraction as follows:
|
|||||||
=== Testing Improvements
|
=== Testing Improvements
|
||||||
|
|
||||||
* The JUnit support in the _Spring TestContext Framework_ now requires JUnit 4.12 or higher.
|
* The JUnit support in the _Spring TestContext Framework_ now requires JUnit 4.12 or higher.
|
||||||
|
* Server-side Spring MVC Test supports expectations on response headers with multiple values.
|
||||||
|
* Server-side Spring MVC Test parses form data request content and populates request parameters.
|
||||||
* Client-side Spring MVC Test supports expectations for form data in the request body.
|
* Client-side Spring MVC Test supports expectations for form data in the request body.
|
||||||
* Server-side Spring MVC Test supports expectations on response headers with multiple values.
|
|
||||||
Reference in New Issue
Block a user