Skip to content

Commit 1af7575

Browse files
committed
Merge rather than add URI vars to data binding values
As of Spring 3.1 URI variables can be used for data binding purposes in addition to request parameters (including query string and form params) In some cases URI variables and request params can overlap (e.g. form contains a child entity with an entityId as hidden form input while the URI contains the entityId of the parent entity) and that can lead to surprises if the application already exists. This change ensures that request parameters are used first and URI vars are added only if they don't overlap. Ideally however an application should not use the same uri variable name as the name of a request parameter where they don't refer to the same value. Issue: SPR-9349 Backport-Issue: SPR-9432 Backport-Commit: 4027b38
1 parent 8143d66 commit 1af7575

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 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.
@@ -17,6 +17,8 @@
1717
package org.springframework.web.servlet.mvc.method.annotation;
1818

1919
import java.util.Map;
20+
import java.util.Map.Entry;
21+
2022
import javax.servlet.ServletRequest;
2123

2224
import org.springframework.beans.MutablePropertyValues;
@@ -54,13 +56,24 @@ public ExtendedServletRequestDataBinder(Object target, String objectName) {
5456
}
5557

5658
/**
57-
* Add URI template variables to the property values used for data binding.
59+
* Merge URI variables into the property values to use for data binding.
5860
*/
59-
@Override
61+
@Override
6062
@SuppressWarnings("unchecked")
6163
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
6264
String attr = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
63-
mpvs.addPropertyValues((Map<String, String>) request.getAttribute(attr));
64-
}
65+
Map<String, String> uriVars = (Map<String, String>) request.getAttribute(attr);
66+
if (uriVars != null) {
67+
for (Entry<String, String> entry : uriVars.entrySet()) {
68+
if (mpvs.contains(entry.getKey())) {
69+
logger.warn("Skipping URI variable '" + entry.getKey()
70+
+ "' since the request contains a bind value with the same name.");
71+
}
72+
else {
73+
mpvs.addPropertyValue(entry.getKey(), entry.getValue());
74+
}
75+
}
76+
}
77+
}
6578

6679
}

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinderTests.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@
3737
public class ExtendedServletRequestDataBinderTests {
3838

3939
private MockHttpServletRequest request;
40-
40+
4141
@Before
4242
public void setup() {
4343
this.request = new MockHttpServletRequest();
4444
}
45-
45+
4646
@Test
4747
public void createBinder() throws Exception {
4848
Map<String, String> uriTemplateVars = new HashMap<String, String>();
4949
uriTemplateVars.put("name", "nameValue");
5050
uriTemplateVars.put("age", "25");
5151
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
52-
52+
5353
TestBean target = new TestBean();
5454
WebDataBinder binder = new ExtendedServletRequestDataBinder(target, "");
5555
((ServletRequestDataBinder) binder).bind(request);
@@ -61,18 +61,18 @@ public void createBinder() throws Exception {
6161
@Test
6262
public void uriTemplateVarAndRequestParam() throws Exception {
6363
request.addParameter("age", "35");
64-
64+
6565
Map<String, String> uriTemplateVars = new HashMap<String, String>();
6666
uriTemplateVars.put("name", "nameValue");
6767
uriTemplateVars.put("age", "25");
6868
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
69-
69+
7070
TestBean target = new TestBean();
7171
WebDataBinder binder = new ExtendedServletRequestDataBinder(target, "");
7272
((ServletRequestDataBinder) binder).bind(request);
7373

7474
assertEquals("nameValue", target.getName());
75-
assertEquals(25, target.getAge());
75+
assertEquals(35, target.getAge());
7676
}
7777

7878
@Test

0 commit comments

Comments
 (0)