MockMvc request builder preserves double slashes
The MockHttpServletRequestBuilder now uses java.net.URI internally rather than UriComponents. This means that for the MockMvcRequestBuilders method variants that accept a java.net.URI we can use it as is. The difference is almost none but it does mean that you can create a URI with double slashes (for testing purposes) and have it remain that way. Issue: SPR-13435
This commit is contained in:
@@ -51,7 +51,6 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||||||
import org.springframework.web.servlet.FlashMap;
|
import org.springframework.web.servlet.FlashMap;
|
||||||
import org.springframework.web.servlet.FlashMapManager;
|
import org.springframework.web.servlet.FlashMapManager;
|
||||||
import org.springframework.web.servlet.support.SessionFlashMapManager;
|
import org.springframework.web.servlet.support.SessionFlashMapManager;
|
||||||
import org.springframework.web.util.UriComponents;
|
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import org.springframework.web.util.UriUtils;
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ public class MockHttpServletRequestBuilder
|
|||||||
|
|
||||||
private final HttpMethod method;
|
private final HttpMethod method;
|
||||||
|
|
||||||
private final UriComponents uriComponents;
|
private final URI url;
|
||||||
|
|
||||||
private final MultiValueMap<String, Object> headers = new LinkedMultiValueMap<String, Object>();
|
private final MultiValueMap<String, Object> headers = new LinkedMultiValueMap<String, Object>();
|
||||||
|
|
||||||
@@ -116,14 +115,11 @@ public class MockHttpServletRequestBuilder
|
|||||||
* the {@code MockHttpServletRequest} can be plugged in via
|
* the {@code MockHttpServletRequest} can be plugged in via
|
||||||
* {@link #with(RequestPostProcessor)}.
|
* {@link #with(RequestPostProcessor)}.
|
||||||
* @param httpMethod the HTTP method (GET, POST, etc)
|
* @param httpMethod the HTTP method (GET, POST, etc)
|
||||||
* @param urlTemplate a URL template; the resulting URL will be encoded
|
* @param url a URL template; the resulting URL will be encoded
|
||||||
* @param urlVariables zero or more URL variables
|
* @param vars zero or more URL variables
|
||||||
*/
|
*/
|
||||||
MockHttpServletRequestBuilder(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) {
|
MockHttpServletRequestBuilder(HttpMethod httpMethod, String url, Object... vars) {
|
||||||
Assert.notNull(httpMethod, "httpMethod is required");
|
this(httpMethod, UriComponentsBuilder.fromUriString(url).buildAndExpand(vars).encode().toUri());
|
||||||
Assert.notNull(urlTemplate, "uriTemplate is required");
|
|
||||||
this.method = httpMethod;
|
|
||||||
this.uriComponents = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(urlVariables).encode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,14 +129,14 @@ public class MockHttpServletRequestBuilder
|
|||||||
* the {@code MockHttpServletRequest} can be plugged in via
|
* the {@code MockHttpServletRequest} can be plugged in via
|
||||||
* {@link #with(RequestPostProcessor)}.
|
* {@link #with(RequestPostProcessor)}.
|
||||||
* @param httpMethod the HTTP method (GET, POST, etc)
|
* @param httpMethod the HTTP method (GET, POST, etc)
|
||||||
* @param uri the URL
|
* @param url the URL
|
||||||
* @since 4.0.3
|
* @since 4.0.3
|
||||||
*/
|
*/
|
||||||
MockHttpServletRequestBuilder(HttpMethod httpMethod, URI uri) {
|
MockHttpServletRequestBuilder(HttpMethod httpMethod, URI url) {
|
||||||
Assert.notNull(httpMethod, "httpMethod is required");
|
Assert.notNull(httpMethod, "httpMethod is required");
|
||||||
Assert.notNull(uri, "uri is required");
|
Assert.notNull(url, "url is required");
|
||||||
this.method = httpMethod;
|
this.method = httpMethod;
|
||||||
this.uriComponents = UriComponentsBuilder.fromUri(uri).build();
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -559,18 +555,18 @@ public class MockHttpServletRequestBuilder
|
|||||||
public final MockHttpServletRequest buildRequest(ServletContext servletContext) {
|
public final MockHttpServletRequest buildRequest(ServletContext servletContext) {
|
||||||
MockHttpServletRequest request = createServletRequest(servletContext);
|
MockHttpServletRequest request = createServletRequest(servletContext);
|
||||||
|
|
||||||
String requestUri = this.uriComponents.getPath();
|
String requestUri = this.url.getRawPath();
|
||||||
request.setRequestURI(requestUri);
|
request.setRequestURI(requestUri);
|
||||||
updatePathRequestProperties(request, requestUri);
|
updatePathRequestProperties(request, requestUri);
|
||||||
|
|
||||||
if (this.uriComponents.getScheme() != null) {
|
if (this.url.getScheme() != null) {
|
||||||
request.setScheme(this.uriComponents.getScheme());
|
request.setScheme(this.url.getScheme());
|
||||||
}
|
}
|
||||||
if (this.uriComponents.getHost() != null) {
|
if (this.url.getHost() != null) {
|
||||||
request.setServerName(uriComponents.getHost());
|
request.setServerName(this.url.getHost());
|
||||||
}
|
}
|
||||||
if (this.uriComponents.getPort() != -1) {
|
if (this.url.getPort() != -1) {
|
||||||
request.setServerPort(this.uriComponents.getPort());
|
request.setServerPort(this.url.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
request.setMethod(this.method.name());
|
request.setMethod(this.method.name());
|
||||||
@@ -582,11 +578,14 @@ public class MockHttpServletRequestBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.uriComponents.getQuery() != null) {
|
if (this.url.getRawQuery() != null) {
|
||||||
request.setQueryString(this.uriComponents.getQuery());
|
request.setQueryString(this.url.getRawQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entry<String, List<String>> entry : this.uriComponents.getQueryParams().entrySet()) {
|
MultiValueMap<String, String> queryParams =
|
||||||
|
UriComponentsBuilder.fromUri(this.url).build().getQueryParams();
|
||||||
|
|
||||||
|
for (Entry<String, List<String>> entry : queryParams.entrySet()) {
|
||||||
for (String value : entry.getValue()) {
|
for (String value : entry.getValue()) {
|
||||||
value = (value != null) ? UriUtils.decode(value, "UTF-8") : null;
|
value = (value != null) ? UriUtils.decode(value, "UTF-8") : null;
|
||||||
request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value);
|
request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
package org.springframework.test.web.servlet.request;
|
package org.springframework.test.web.servlet.request;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -91,6 +93,16 @@ public class MockHttpServletRequestBuilderTests {
|
|||||||
assertEquals("/foo%20bar", request.getRequestURI());
|
assertEquals("/foo%20bar", request.getRequestURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPR-13435
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestUriWithDoubleSlashes() throws URISyntaxException {
|
||||||
|
this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, new URI("/test//currentlyValid/0"));
|
||||||
|
MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
|
||||||
|
|
||||||
|
assertEquals("/test//currentlyValid/0", request.getRequestURI());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextPathEmpty() {
|
public void contextPathEmpty() {
|
||||||
this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/foo");
|
this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/foo");
|
||||||
|
|||||||
Reference in New Issue
Block a user