Skip to content

Commit d91a419

Browse files
committed
Fix SpEL JavaBean compliance for setters
Prior to this change, SpEL was capable of handling getter methods for property names having a lowercase first letter and uppercase second letter such as: public String getiD() { ... } However, setters with the same naming arrangement were not supported, e.g.: public void setiD() { ... } This commit ensures that setters and getters are treated by SpEL equally in this regard, such that "iD"-style property names may be used anywhere within SpEL expressions. Issue: SPR-10122, SPR-9123
1 parent 55a0574 commit d91a419

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -311,23 +311,18 @@ private Field findField(String name, Class<?> clazz, Object target) {
311311
*/
312312
protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
313313
Method[] ms = clazz.getMethods();
314-
String propertyWriteMethodSuffix;
315-
if (propertyName.length() > 1 && Character.isUpperCase(propertyName.charAt(1))) {
316-
propertyWriteMethodSuffix = propertyName;
317-
}
318-
else {
319-
propertyWriteMethodSuffix = StringUtils.capitalize(propertyName);
320-
}
314+
String propertyMethodSuffix = getPropertyMethodSuffix(propertyName);
315+
321316
// Try "get*" method...
322-
String getterName = "get" + propertyWriteMethodSuffix;
317+
String getterName = "get" + propertyMethodSuffix;
323318
for (Method method : ms) {
324319
if (!method.isBridge() && method.getName().equals(getterName) && method.getParameterTypes().length == 0 &&
325320
(!mustBeStatic || Modifier.isStatic(method.getModifiers()))) {
326321
return method;
327322
}
328323
}
329324
// Try "is*" method...
330-
getterName = "is" + propertyWriteMethodSuffix;
325+
getterName = "is" + propertyMethodSuffix;
331326
for (Method method : ms) {
332327
if (!method.isBridge() && method.getName().equals(getterName) && method.getParameterTypes().length == 0 &&
333328
(boolean.class.equals(method.getReturnType()) || Boolean.class.equals(method.getReturnType())) &&
@@ -343,7 +338,7 @@ protected Method findGetterForProperty(String propertyName, Class<?> clazz, bool
343338
*/
344339
protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
345340
Method[] methods = clazz.getMethods();
346-
String setterName = "set" + StringUtils.capitalize(propertyName);
341+
String setterName = "set" + getPropertyMethodSuffix(propertyName);
347342
for (Method method : methods) {
348343
if (!method.isBridge() && method.getName().equals(setterName) && method.getParameterTypes().length == 1 &&
349344
(!mustBeStatic || Modifier.isStatic(method.getModifiers()))) {
@@ -353,6 +348,15 @@ protected Method findSetterForProperty(String propertyName, Class<?> clazz, bool
353348
return null;
354349
}
355350

351+
protected String getPropertyMethodSuffix(String propertyName) {
352+
if (propertyName.length() > 1 && Character.isUpperCase(propertyName.charAt(1))) {
353+
return propertyName;
354+
}
355+
else {
356+
return StringUtils.capitalize(propertyName);
357+
}
358+
}
359+
356360
/**
357361
* Find a field of a certain name on a specified class
358362
*/

spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import java.util.ArrayList;
2323
import java.util.List;
2424

25-
import junit.framework.Assert;
25+
import org.junit.Assert;
2626
import org.junit.Test;
2727

2828
import org.springframework.core.convert.TypeDescriptor;
@@ -329,6 +329,10 @@ public void testReflectivePropertyResolver() throws Exception {
329329
// note: "Id" is not a valid JavaBean name, nevertheless it is treated as "id"
330330
Assert.assertEquals("id",rpr.read(ctx,t,"Id").getValue());
331331
Assert.assertTrue(rpr.canRead(ctx,t,"Id"));
332+
333+
// SPR-10122, ReflectivePropertyAccessor JavaBean property names compliance tests - setters
334+
rpr.write(ctx, t, "pEBS","Test String");
335+
Assert.assertEquals("Test String",rpr.read(ctx,t,"pEBS").getValue());
332336
}
333337

334338
@Test
@@ -419,6 +423,7 @@ static class Tester {
419423
String iD = "iD";
420424
String id = "id";
421425
String ID = "ID";
426+
String pEBS = "pEBS";
422427

423428
public String getProperty() { return property; }
424429
public void setProperty(String value) { property = value; }
@@ -434,6 +439,14 @@ static class Tester {
434439
public String getId() { return id; }
435440

436441
public String getID() { return ID; }
442+
443+
public String getpEBS() {
444+
return pEBS;
445+
}
446+
447+
public void setpEBS(String pEBS) {
448+
this.pEBS = pEBS;
449+
}
437450
}
438451

439452
static class Super {

0 commit comments

Comments
 (0)