@RequestParam/RequestHeader/CookieValue's defaultValue allows for declaring empty String (SPR-6791)

This commit is contained in:
Juergen Hoeller 2010-02-15 12:10:55 +00:00
parent 83231997c0
commit 97059f4e18
6 changed files with 58 additions and 16 deletions

View File

@ -199,7 +199,7 @@ public class ServletAnnotationControllerTests {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response); servlet.service(request, response);
assertEquals("foo-null-bar", response.getContentAsString()); assertEquals("foo--bar", response.getContentAsString());
} }
@Test @Test
@ -1970,7 +1970,7 @@ public class ServletAnnotationControllerTests {
@RequestMapping("/myPath.do") @RequestMapping("/myPath.do")
public void myHandle(@RequestParam(value = "id", defaultValue = "foo") String id, public void myHandle(@RequestParam(value = "id", defaultValue = "foo") String id,
@RequestParam(value = "otherId", required = false) String id2, @RequestParam(value = "otherId", defaultValue = "") String id2,
@RequestHeader(defaultValue = "bar") String header, @RequestHeader(defaultValue = "bar") String header,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
response.getWriter().write(String.valueOf(id) + "-" + String.valueOf(id2) + "-" + String.valueOf(header)); response.getWriter().write(String.valueOf(id) + "-" + String.valueOf(id2) + "-" + String.valueOf(header));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -63,6 +63,6 @@ public @interface CookieValue {
* The default value to use as a fallback. Supplying a default value implicitly * The default value to use as a fallback. Supplying a default value implicitly
* sets {@link #required()} to false. * sets {@link #required()} to false.
*/ */
String defaultValue() default ""; String defaultValue() default ValueConstants.DEFAULT_NONE;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -58,6 +58,6 @@ public @interface RequestHeader {
* The default value to use as a fallback. Supplying a default value implicitely * The default value to use as a fallback. Supplying a default value implicitely
* sets {@link #required()} to false. * sets {@link #required()} to false.
*/ */
String defaultValue() default ""; String defaultValue() default ValueConstants.DEFAULT_NONE;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -60,6 +60,6 @@ public @interface RequestParam {
* The default value to use as a fallback. Supplying a default value implicitly * The default value to use as a fallback. Supplying a default value implicitly
* sets {@link #required()} to false. * sets {@link #required()} to false.
*/ */
String defaultValue() default ""; String defaultValue() default ValueConstants.DEFAULT_NONE;
} }

View File

@ -0,0 +1,38 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
/**
* Common value constants shared between bind annotations.
*
* @author Juergen Hoeller
* @since 3.0.1
*/
public interface ValueConstants {
/**
* Constant defining a value for no default - as a replacement for
* <code>null</code> which we cannot use in annotation attributes.
* <p>This is an artificial arrangement of 16 unicode characters,
* with its sole purpose being to never match user-declared values.
* @see RequestParam#defaultValue()
* @see RequestHeader#defaultValue()
* @see CookieValue#defaultValue()
*/
String DEFAULT_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n";
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -50,7 +50,6 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;
@ -63,6 +62,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ValueConstants;
import org.springframework.web.bind.support.DefaultSessionAttributeStore; import org.springframework.web.bind.support.DefaultSessionAttributeStore;
import org.springframework.web.bind.support.SessionAttributeStore; import org.springframework.web.bind.support.SessionAttributeStore;
import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.bind.support.SessionStatus;
@ -200,14 +200,14 @@ public class HandlerMethodInvoker {
RequestParam requestParam = (RequestParam) paramAnn; RequestParam requestParam = (RequestParam) paramAnn;
paramName = requestParam.value(); paramName = requestParam.value();
required = requestParam.required(); required = requestParam.required();
defaultValue = requestParam.defaultValue(); defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
found++; found++;
} }
else if (RequestHeader.class.isInstance(paramAnn)) { else if (RequestHeader.class.isInstance(paramAnn)) {
RequestHeader requestHeader = (RequestHeader) paramAnn; RequestHeader requestHeader = (RequestHeader) paramAnn;
headerName = requestHeader.value(); headerName = requestHeader.value();
required = requestHeader.required(); required = requestHeader.required();
defaultValue = requestHeader.defaultValue(); defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
found++; found++;
} }
else if (RequestBody.class.isInstance(paramAnn)) { else if (RequestBody.class.isInstance(paramAnn)) {
@ -218,7 +218,7 @@ public class HandlerMethodInvoker {
CookieValue cookieValue = (CookieValue) paramAnn; CookieValue cookieValue = (CookieValue) paramAnn;
cookieName = cookieValue.value(); cookieName = cookieValue.value();
required = cookieValue.required(); required = cookieValue.required();
defaultValue = cookieValue.defaultValue(); defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());
found++; found++;
} }
else if (PathVariable.class.isInstance(paramAnn)) { else if (PathVariable.class.isInstance(paramAnn)) {
@ -430,7 +430,7 @@ public class HandlerMethodInvoker {
} }
} }
if (paramValue == null) { if (paramValue == null) {
if (StringUtils.hasText(defaultValue)) { if (defaultValue != null) {
paramValue = resolveDefaultValue(defaultValue); paramValue = resolveDefaultValue(defaultValue);
} }
else if (required) { else if (required) {
@ -483,7 +483,7 @@ public class HandlerMethodInvoker {
headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues); headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues);
} }
if (headerValue == null) { if (headerValue == null) {
if (StringUtils.hasText(defaultValue)) { if (defaultValue != null) {
headerValue = resolveDefaultValue(defaultValue); headerValue = resolveDefaultValue(defaultValue);
} }
else if (required) { else if (required) {
@ -566,7 +566,7 @@ public class HandlerMethodInvoker {
} }
Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest); Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest);
if (cookieValue == null) { if (cookieValue == null) {
if (StringUtils.hasText(defaultValue)) { if (defaultValue != null) {
cookieValue = resolveDefaultValue(defaultValue); cookieValue = resolveDefaultValue(defaultValue);
} }
else if (required) { else if (required) {
@ -762,6 +762,10 @@ public class HandlerMethodInvoker {
throw new UnsupportedOperationException("@RequestBody not supported"); throw new UnsupportedOperationException("@RequestBody not supported");
} }
protected String parseDefaultValueAttribute(String value) {
return (ValueConstants.DEFAULT_NONE.equals(value) ? null : value);
}
protected Object resolveDefaultValue(String value) { protected Object resolveDefaultValue(String value) {
return value; return value;
} }