queryParam and replaceParam with List

See gh-23114
This commit is contained in:
Dmytro Nosan 2019-06-12 15:49:19 +03:00 committed by Rossen Stoyanchev
parent 0d3e5db3ff
commit ea10ee5265
4 changed files with 118 additions and 5 deletions

View File

@ -17,6 +17,7 @@
package org.springframework.web.util; package org.springframework.web.util;
import java.net.URI; import java.net.URI;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -326,12 +327,24 @@ public class DefaultUriBuilderFactory implements UriBuilderFactory {
return this; return this;
} }
@Override
public DefaultUriBuilder queryParams(String name, @Nullable Collection<?> values) {
this.uriComponentsBuilder.queryParams(name, values);
return this;
}
@Override @Override
public DefaultUriBuilder replaceQueryParam(String name, Object... values) { public DefaultUriBuilder replaceQueryParam(String name, Object... values) {
this.uriComponentsBuilder.replaceQueryParam(name, values); this.uriComponentsBuilder.replaceQueryParam(name, values);
return this; return this;
} }
@Override
public DefaultUriBuilder replaceQueryParams(String name, @Nullable Collection<?> values) {
this.uriComponentsBuilder.replaceQueryParams(name, values);
return this;
}
@Override @Override
public DefaultUriBuilder queryParams(MultiValueMap<String, String> params) { public DefaultUriBuilder queryParams(MultiValueMap<String, String> params) {
this.uriComponentsBuilder.queryParams(params); this.uriComponentsBuilder.queryParams(params);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 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.web.util; package org.springframework.web.util;
import java.net.URI; import java.net.URI;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -124,9 +125,22 @@ public interface UriBuilder {
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}. * only (i.e. {@code ?foo} instead of {@code ?foo=bar}.
* @param name the query parameter name * @param name the query parameter name
* @param values the query parameter values * @param values the query parameter values
* @see #queryParams(String, Collection)
*/ */
UriBuilder queryParam(String name, Object... values); UriBuilder queryParam(String name, Object... values);
/**
* Append the given query parameter to the existing query parameters. The
* given name or any of the values may contain URI template variables. If no
* values are given, the resulting URI will contain the query parameter name
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}.
* @param name the query parameter name
* @param values the query parameter values
* @since 5.2.0
* @see #queryParam(String, Object...)
*/
UriBuilder queryParams(String name, @Nullable Collection<?> values);
/** /**
* Add the given query parameters. * Add the given query parameters.
* @param params the params * @param params the params
@ -138,9 +152,20 @@ public interface UriBuilder {
* the same parameter. If no values are given, the query parameter is removed. * the same parameter. If no values are given, the query parameter is removed.
* @param name the query parameter name * @param name the query parameter name
* @param values the query parameter values * @param values the query parameter values
* @see #replaceQueryParams(String, Collection)
*/ */
UriBuilder replaceQueryParam(String name, Object... values); UriBuilder replaceQueryParam(String name, Object... values);
/**
* Set the query parameter values overriding all existing query values for
* the same parameter. If no values are given, the query parameter is removed.
* @param name the query parameter name
* @param values the query parameter values
* @since 5.2.0
* @see #replaceQueryParam(String, Object...)
*/
UriBuilder replaceQueryParams(String name, @Nullable Collection<?> values);
/** /**
* Set the query parameter values overriding all existing query values. * Set the query parameter values overriding all existing query values.
* @param params the query parameter name * @param params the query parameter name

View File

@ -20,6 +20,9 @@ import java.net.URI;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -31,6 +34,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -696,11 +700,28 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
* @param name the query parameter name * @param name the query parameter name
* @param values the query parameter values * @param values the query parameter values
* @return this UriComponentsBuilder * @return this UriComponentsBuilder
* @see #queryParams(String, Collection)
*/ */
@Override @Override
public UriComponentsBuilder queryParam(String name, Object... values) { public UriComponentsBuilder queryParam(String name, Object... values) {
return queryParams(name, (!ObjectUtils.isEmpty(values) ? Arrays.asList(values) : Collections.emptyList()));
}
/**
* Append the given query parameter to the existing query parameters. The
* given name or any of the values may contain URI template variables. If no
* values are given, the resulting URI will contain the query parameter name
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}).
* @param name the query parameter name
* @param values the query parameter values
* @return this UriComponentsBuilder
* @since 5.2.0
* @see #queryParam(String, Object...)
*/
@Override
public UriComponentsBuilder queryParams(String name, @Nullable Collection<?> values) {
Assert.notNull(name, "Name must not be null"); Assert.notNull(name, "Name must not be null");
if (!ObjectUtils.isEmpty(values)) { if (!CollectionUtils.isEmpty(values)) {
for (Object value : values) { for (Object value : values) {
String valueAsString = (value != null ? value.toString() : null); String valueAsString = (value != null ? value.toString() : null);
this.queryParams.add(name, valueAsString); this.queryParams.add(name, valueAsString);
@ -733,13 +754,28 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
* @param name the query parameter name * @param name the query parameter name
* @param values the query parameter values * @param values the query parameter values
* @return this UriComponentsBuilder * @return this UriComponentsBuilder
* @see #replaceQueryParams(String, Collection)
*/ */
@Override @Override
public UriComponentsBuilder replaceQueryParam(String name, Object... values) { public UriComponentsBuilder replaceQueryParam(String name, Object... values) {
return replaceQueryParams(name, (!ObjectUtils.isEmpty(values) ? Arrays.asList(values) : Collections.emptyList()));
}
/**
* Set the query parameter values overriding all existing query values for
* the same parameter. If no values are given, the query parameter is removed.
* @param name the query parameter name
* @param values the query parameter values
* @return this UriComponentsBuilder
* @see #replaceQueryParam(String, Object...)
* @since 5.2.0
*/
@Override
public UriComponentsBuilder replaceQueryParams(String name, @Nullable Collection<?> values) {
Assert.notNull(name, "Name must not be null"); Assert.notNull(name, "Name must not be null");
this.queryParams.remove(name); this.queryParams.remove(name);
if (!ObjectUtils.isEmpty(values)) { if (!CollectionUtils.isEmpty(values)) {
queryParam(name, values); queryParams(name, values);
} }
resetSchemeSpecificPart(); resetSchemeSpecificPart();
return this; return this;

View File

@ -643,7 +643,7 @@ public class UriComponentsBuilderTests {
} }
@Test @Test
public void queryParams() { public void queryParam() {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance(); UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
UriComponents result = builder.queryParam("baz", "qux", 42).build(); UriComponents result = builder.queryParam("baz", "qux", 42).build();
@ -654,6 +654,18 @@ public class UriComponentsBuilderTests {
assertThat(result.getQueryParams()).isEqualTo(expectedQueryParams); assertThat(result.getQueryParams()).isEqualTo(expectedQueryParams);
} }
@Test
public void queryParams() {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
UriComponents result = builder.queryParams("baz", Arrays.asList("qux", 42)).build();
assertThat(result.getQuery()).isEqualTo("baz=qux&baz=42");
MultiValueMap<String, String> expectedQueryParams = new LinkedMultiValueMap<>(2);
expectedQueryParams.add("baz", "qux");
expectedQueryParams.add("baz", "42");
assertThat(result.getQueryParams()).isEqualTo(expectedQueryParams);
}
@Test @Test
public void emptyQueryParam() { public void emptyQueryParam() {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance(); UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
@ -665,6 +677,18 @@ public class UriComponentsBuilderTests {
assertThat(result.getQueryParams()).isEqualTo(expectedQueryParams); assertThat(result.getQueryParams()).isEqualTo(expectedQueryParams);
} }
@Test
public void emptyQueryParams() {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
UriComponents result = builder.queryParams("baz", Collections.emptyList()).queryParams("foo", null).build();
assertThat(result.getQuery()).isEqualTo("baz&foo");
MultiValueMap<String, String> expectedQueryParams = new LinkedMultiValueMap<>(2);
expectedQueryParams.add("baz", null);
expectedQueryParams.add("foo", null);
assertThat(result.getQueryParams()).isEqualTo(expectedQueryParams);
}
@Test @Test
public void replaceQueryParam() { public void replaceQueryParam() {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance().queryParam("baz", "qux", 42); UriComponentsBuilder builder = UriComponentsBuilder.newInstance().queryParam("baz", "qux", 42);
@ -680,6 +704,21 @@ public class UriComponentsBuilderTests {
assertThat(result.getQuery()).as("Query param should have been deleted").isNull(); assertThat(result.getQuery()).as("Query param should have been deleted").isNull();
} }
@Test
public void replaceQueryParams() {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance().queryParams("baz", Arrays.asList("qux", 42));
builder.replaceQueryParams("baz", Arrays.asList("xuq", 24));
UriComponents result = builder.build();
assertThat(result.getQuery()).isEqualTo("baz=xuq&baz=24");
builder = UriComponentsBuilder.newInstance().queryParams("baz", Arrays.asList("qux", 42));
builder.replaceQueryParams("baz", Collections.emptyList());
result = builder.build();
assertThat(result.getQuery()).as("Query param should have been deleted").isNull();
}
@Test @Test
public void buildAndExpandHierarchical() { public void buildAndExpandHierarchical() {
UriComponents result = UriComponentsBuilder.fromPath("/{foo}").buildAndExpand("fooValue"); UriComponents result = UriComponentsBuilder.fromPath("/{foo}").buildAndExpand("fooValue");