From 203b22b2462bd2c05791fde937f69312e2cfe6c3 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 11 Feb 2013 09:39:51 -0800 Subject: [PATCH] UriComponentsBuilder supports query without value Fix UriComponentsBuilder to support query parameters that do not include a value without losing '='. The following styles are now supported: http://example.com/foo?bar=baz http://example.com/foo?bar= http://example.com/foo?bar Issue: SPR-10215 --- .../web/util/UriComponentsBuilder.java | 10 +++++---- .../web/util/UriComponentsBuilderTests.java | 22 ++++++++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index 141cd7b86e..4a1aa85af9 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ import org.springframework.util.StringUtils; */ public class UriComponentsBuilder { - private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)=?([^&]+)?"); + private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)(=?)([^&]+)?"); private static final String SCHEME_PATTERN = "([^:/?#]+):"; @@ -496,8 +496,10 @@ public class UriComponentsBuilder { Matcher m = QUERY_PARAM_PATTERN.matcher(query); while (m.find()) { String name = m.group(1); - String value = m.group(2); - queryParam(name, value); + String eq = m.group(2); + String value = m.group(3); + queryParam(name, (value != null ? value : + (StringUtils.hasLength(eq) ? "" : null))); } } else { diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index 8205ca6cdf..afa1691008 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +27,12 @@ import org.junit.Test; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.*; /** * @author Arjen Poutsma + * @author Phillip Webb */ public class UriComponentsBuilderTests { @@ -312,4 +314,22 @@ public class UriComponentsBuilderTests { assertEquals("mailto:foo@example.com", result.toUriString()); } + @Test + public void queryParamWithValueWithEquals() throws Exception { + UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/foo?bar=baz").build(); + assertThat(uriComponents.toUriString(), equalTo("http://example.com/foo?bar=baz")); + } + + @Test + public void queryParamWithoutValueWithEquals() throws Exception { + UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/foo?bar=").build(); + assertThat(uriComponents.toUriString(), equalTo("http://example.com/foo?bar=")); + } + + @Test + public void queryParamWithoutValueWithoutEquals() throws Exception { + UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/foo?bar").build(); + assertThat(uriComponents.toUriString(), equalTo("http://example.com/foo?bar")); + } + }