提交 4027b389 编写于 作者: R Rossen Stoyanchev

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
上级 5330c52e
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
......@@ -17,6 +17,8 @@
package org.springframework.web.servlet.mvc.method.annotation;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletRequest;
import org.springframework.beans.MutablePropertyValues;
......@@ -54,13 +56,24 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder {
}
/**
* Add URI template variables to the property values used for data binding.
* Merge URI variables into the property values to use for data binding.
*/
@Override
@Override
@SuppressWarnings("unchecked")
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
String attr = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
mpvs.addPropertyValues((Map<String, String>) request.getAttribute(attr));
}
Map<String, String> uriVars = (Map<String, String>) request.getAttribute(attr);
if (uriVars != null) {
for (Entry<String, String> entry : uriVars.entrySet()) {
if (mpvs.contains(entry.getKey())) {
logger.warn("Skipping URI variable '" + entry.getKey()
+ "' since the request contains a bind value with the same name.");
}
else {
mpvs.addPropertyValue(entry.getKey(), entry.getValue());
}
}
}
}
}
......@@ -37,19 +37,19 @@ import org.springframework.web.servlet.HandlerMapping;
public class ExtendedServletRequestDataBinderTests {
private MockHttpServletRequest request;
@Before
public void setup() {
this.request = new MockHttpServletRequest();
}
@Test
public void createBinder() throws Exception {
Map<String, String> uriTemplateVars = new HashMap<String, String>();
uriTemplateVars.put("name", "nameValue");
uriTemplateVars.put("age", "25");
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
TestBean target = new TestBean();
WebDataBinder binder = new ExtendedServletRequestDataBinder(target, "");
((ServletRequestDataBinder) binder).bind(request);
......@@ -61,18 +61,18 @@ public class ExtendedServletRequestDataBinderTests {
@Test
public void uriTemplateVarAndRequestParam() throws Exception {
request.addParameter("age", "35");
Map<String, String> uriTemplateVars = new HashMap<String, String>();
uriTemplateVars.put("name", "nameValue");
uriTemplateVars.put("age", "25");
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
TestBean target = new TestBean();
WebDataBinder binder = new ExtendedServletRequestDataBinder(target, "");
((ServletRequestDataBinder) binder).bind(request);
assertEquals("nameValue", target.getName());
assertEquals(25, target.getAge());
assertEquals(35, target.getAge());
}
@Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册