Skip to content

Commit 97059f4

Browse files
committed
@RequestParam/RequestHeader/CookieValue's defaultValue allows for declaring empty String (SPR-6791)
1 parent 8323199 commit 97059f4

File tree

6 files changed

+58
-16
lines changed

6 files changed

+58
-16
lines changed

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public void defaultParameters() throws Exception {
199199
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do");
200200
MockHttpServletResponse response = new MockHttpServletResponse();
201201
servlet.service(request, response);
202-
assertEquals("foo-null-bar", response.getContentAsString());
202+
assertEquals("foo--bar", response.getContentAsString());
203203
}
204204

205205
@Test
@@ -1970,7 +1970,7 @@ public static class DefaultValueParamController {
19701970

19711971
@RequestMapping("/myPath.do")
19721972
public void myHandle(@RequestParam(value = "id", defaultValue = "foo") String id,
1973-
@RequestParam(value = "otherId", required = false) String id2,
1973+
@RequestParam(value = "otherId", defaultValue = "") String id2,
19741974
@RequestHeader(defaultValue = "bar") String header,
19751975
HttpServletResponse response) throws IOException {
19761976
response.getWriter().write(String.valueOf(id) + "-" + String.valueOf(id2) + "-" + String.valueOf(header));

org.springframework.web/src/main/java/org/springframework/web/bind/annotation/CookieValue.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -63,6 +63,6 @@
6363
* The default value to use as a fallback. Supplying a default value implicitly
6464
* sets {@link #required()} to false.
6565
*/
66-
String defaultValue() default "";
66+
String defaultValue() default ValueConstants.DEFAULT_NONE;
6767

6868
}

org.springframework.web/src/main/java/org/springframework/web/bind/annotation/RequestHeader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -58,6 +58,6 @@
5858
* The default value to use as a fallback. Supplying a default value implicitely
5959
* sets {@link #required()} to false.
6060
*/
61-
String defaultValue() default "";
61+
String defaultValue() default ValueConstants.DEFAULT_NONE;
6262

6363
}

org.springframework.web/src/main/java/org/springframework/web/bind/annotation/RequestParam.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -60,6 +60,6 @@
6060
* The default value to use as a fallback. Supplying a default value implicitly
6161
* sets {@link #required()} to false.
6262
*/
63-
String defaultValue() default "";
63+
String defaultValue() default ValueConstants.DEFAULT_NONE;
6464

6565
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2002-2010 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.bind.annotation;
18+
19+
/**
20+
* Common value constants shared between bind annotations.
21+
*
22+
* @author Juergen Hoeller
23+
* @since 3.0.1
24+
*/
25+
public interface ValueConstants {
26+
27+
/**
28+
* Constant defining a value for no default - as a replacement for
29+
* <code>null</code> which we cannot use in annotation attributes.
30+
* <p>This is an artificial arrangement of 16 unicode characters,
31+
* with its sole purpose being to never match user-declared values.
32+
* @see RequestParam#defaultValue()
33+
* @see RequestHeader#defaultValue()
34+
* @see CookieValue#defaultValue()
35+
*/
36+
String DEFAULT_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n";
37+
38+
}

org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,7 +50,6 @@
5050
import org.springframework.util.LinkedMultiValueMap;
5151
import org.springframework.util.MultiValueMap;
5252
import org.springframework.util.ReflectionUtils;
53-
import org.springframework.util.StringUtils;
5453
import org.springframework.validation.BindException;
5554
import org.springframework.validation.BindingResult;
5655
import org.springframework.validation.Errors;
@@ -63,6 +62,7 @@
6362
import org.springframework.web.bind.annotation.RequestBody;
6463
import org.springframework.web.bind.annotation.RequestHeader;
6564
import org.springframework.web.bind.annotation.RequestParam;
65+
import org.springframework.web.bind.annotation.ValueConstants;
6666
import org.springframework.web.bind.support.DefaultSessionAttributeStore;
6767
import org.springframework.web.bind.support.SessionAttributeStore;
6868
import org.springframework.web.bind.support.SessionStatus;
@@ -200,14 +200,14 @@ private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
200200
RequestParam requestParam = (RequestParam) paramAnn;
201201
paramName = requestParam.value();
202202
required = requestParam.required();
203-
defaultValue = requestParam.defaultValue();
203+
defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
204204
found++;
205205
}
206206
else if (RequestHeader.class.isInstance(paramAnn)) {
207207
RequestHeader requestHeader = (RequestHeader) paramAnn;
208208
headerName = requestHeader.value();
209209
required = requestHeader.required();
210-
defaultValue = requestHeader.defaultValue();
210+
defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
211211
found++;
212212
}
213213
else if (RequestBody.class.isInstance(paramAnn)) {
@@ -218,7 +218,7 @@ else if (CookieValue.class.isInstance(paramAnn)) {
218218
CookieValue cookieValue = (CookieValue) paramAnn;
219219
cookieName = cookieValue.value();
220220
required = cookieValue.required();
221-
defaultValue = cookieValue.defaultValue();
221+
defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());
222222
found++;
223223
}
224224
else if (PathVariable.class.isInstance(paramAnn)) {
@@ -430,7 +430,7 @@ private Object resolveRequestParam(String paramName, boolean required, String de
430430
}
431431
}
432432
if (paramValue == null) {
433-
if (StringUtils.hasText(defaultValue)) {
433+
if (defaultValue != null) {
434434
paramValue = resolveDefaultValue(defaultValue);
435435
}
436436
else if (required) {
@@ -483,7 +483,7 @@ private Object resolveRequestHeader(String headerName, boolean required, String
483483
headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues);
484484
}
485485
if (headerValue == null) {
486-
if (StringUtils.hasText(defaultValue)) {
486+
if (defaultValue != null) {
487487
headerValue = resolveDefaultValue(defaultValue);
488488
}
489489
else if (required) {
@@ -566,7 +566,7 @@ private Object resolveCookieValue(String cookieName, boolean required, String de
566566
}
567567
Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest);
568568
if (cookieValue == null) {
569-
if (StringUtils.hasText(defaultValue)) {
569+
if (defaultValue != null) {
570570
cookieValue = resolveDefaultValue(defaultValue);
571571
}
572572
else if (required) {
@@ -762,6 +762,10 @@ protected HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) t
762762
throw new UnsupportedOperationException("@RequestBody not supported");
763763
}
764764

765+
protected String parseDefaultValueAttribute(String value) {
766+
return (ValueConstants.DEFAULT_NONE.equals(value) ? null : value);
767+
}
768+
765769
protected Object resolveDefaultValue(String value) {
766770
return value;
767771
}

0 commit comments

Comments
 (0)