From 07125638f45a43370933602e7d36cdd29f2b7830 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 28 Oct 2021 20:42:55 +0200 Subject: [PATCH] #1696 - Re-instantiate conversion for request parameter template variables. When adding a request parameter template variable and the URI part of the template already contains a request parameter we now automatically turn the variable type into request parameter continuation. That apparently got lost in the move to level 4 URI templates in #1583. --- .../java/org/springframework/hateoas/UriTemplate.java | 9 ++++++++- .../org/springframework/hateoas/UriTemplateUnitTest.java | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/hateoas/UriTemplate.java b/src/main/java/org/springframework/hateoas/UriTemplate.java index c9623dfe..1e3da868 100644 --- a/src/main/java/org/springframework/hateoas/UriTemplate.java +++ b/src/main/java/org/springframework/hateoas/UriTemplate.java @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import org.springframework.hateoas.TemplateVariable.VariableType; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.util.UriBuilderFactory; import org.springframework.web.util.UriComponents; @@ -177,8 +178,9 @@ public class UriTemplate implements Iterable, Serializable { for (TemplateVariable variable : variables) { + MultiValueMap parameters = components.getQueryParams(); boolean isRequestParam = variable.isRequestParameterVariable(); - boolean alreadyPresent = components.getQueryParams().containsKey(variable.getName()); + boolean alreadyPresent = parameters.containsKey(variable.getName()); if (isRequestParam && alreadyPresent) { continue; @@ -188,6 +190,11 @@ public class UriTemplate implements Iterable, Serializable { continue; } + // Use request parameter continuation if base contains parameters already + if (!parameters.isEmpty() && variable.getType().equals(VariableType.REQUEST_PARAM)) { + variable = variable.withType(VariableType.REQUEST_PARAM_CONTINUED); + } + ExpandGroup existing = groups.findLastExpandGroupOfType(variable.getType()); ExpandGroup group = new ExpandGroup(Collections.singletonList(variable)); diff --git a/src/test/java/org/springframework/hateoas/UriTemplateUnitTest.java b/src/test/java/org/springframework/hateoas/UriTemplateUnitTest.java index 63dafb3c..49980a9e 100755 --- a/src/test/java/org/springframework/hateoas/UriTemplateUnitTest.java +++ b/src/test/java/org/springframework/hateoas/UriTemplateUnitTest.java @@ -366,6 +366,15 @@ class UriTemplateUnitTest { assertThat(uri).isEqualTo(URI.create("/foo/first/second")); } + @Test // #1696 + void adaptsRequestParamVariableToContinuationIfBaseUriContainsParameter() { + + UriTemplate template = UriTemplate.of("/path/{bar}/foo.zip?type=foo") + .with(new TemplateVariable("foobar", VariableType.REQUEST_PARAM)); + + assertThat(template.toString()).isEqualTo("/path/{bar}/foo.zip?type=foo{&foobar}"); + } + private static void assertVariables(UriTemplate template, TemplateVariable... variables) { assertVariables(template, Arrays.asList(variables)); }