diff --git a/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java b/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java
index 31760c2ab5..83c25fccc8 100644
--- a/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java
+++ b/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java
@@ -331,6 +331,17 @@ public enum MapperFeature implements ConfigFeature
*/
USE_STD_BEAN_NAMING(false),
+ /**
+ * Feature that when enabled will allow explicitly named properties (i.e., fields or methods
+ * annotated with {@link com.fasterxml.jackson.annotation.JsonProperty}("explicitName")) to
+ * be re-named by a {@link PropertyNamingStrategy}, if one is configured.
+ *
+ * Feature is disabled by default.
+ *
+ * @since 2.6
+ */
+ ALLOW_EXPLICIT_PROPERTY_RENAMING(false),
+
/*
/******************************************************
/* Other features
diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java
index 1fb5780a25..c083852cce 100644
--- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java
+++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java
@@ -785,8 +785,9 @@ protected void _renameUsing(Map propMap,
PropertyName fullName = prop.getFullName();
String rename = null;
// As per [#428](https://github.com/FasterXML/jackson-databind/issues/428) need
- // to skip renaming if property has explicitly defined name
- if (!prop.isExplicitlyNamed()) {
+ // to skip renaming if property has explicitly defined name, unless feature
+ // is enabled
+ if (!prop.isExplicitlyNamed() || _config.isEnabled(MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING)) {
if (_forSerialization) {
if (prop.hasGetter()) {
rename = naming.nameForGetterMethod(_config, prop.getGetter(), fullName.getSimpleName());
diff --git a/src/test/java/com/fasterxml/jackson/databind/introspect/TestNamingStrategyStd.java b/src/test/java/com/fasterxml/jackson/databind/introspect/TestNamingStrategyStd.java
index ccd76c0700..96be4a6d28 100644
--- a/src/test/java/com/fasterxml/jackson/databind/introspect/TestNamingStrategyStd.java
+++ b/src/test/java/com/fasterxml/jackson/databind/introspect/TestNamingStrategyStd.java
@@ -7,6 +7,7 @@
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.BaseMapTest;
+import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
@@ -316,4 +317,41 @@ public void testNamingWithObjectNode() throws Exception
assertEquals(2, result.json.size());
assertEquals("bing", result.json.path("baz").asText());
}
+
+ static class ExplicitBean {
+ @JsonProperty("firstName")
+ String userFirstName = "Peter";
+ @JsonProperty("lastName")
+ String userLastName = "Venkman";
+ @JsonProperty
+ String userAge = "35";
+ }
+
+ public void testExplicitRename() throws Exception {
+ ObjectMapper m = new ObjectMapper();
+ m.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
+ m.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
+ // by default, renaming will not take place on explicitly named fields
+ assertEquals(aposToQuotes("{'firstName':'Peter','lastName':'Venkman','user_age':'35'}"),
+ m.writeValueAsString(new ExplicitBean()));
+
+ m = new ObjectMapper();
+ m.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
+ m.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
+ m.enable(MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING);
+ // w/ feature enabled, ALL property names should get re-written
+ assertEquals(aposToQuotes("{'first_name':'Peter','last_name':'Venkman','user_age':'35'}"),
+ m.writeValueAsString(new ExplicitBean()));
+
+ // test deserialization as well
+ ExplicitBean bean =
+ m.readValue(aposToQuotes("{'first_name':'Egon','last_name':'Spengler','user_age':'32'}"),
+ ExplicitBean.class);
+
+ assertNotNull(bean);
+ assertEquals("Egon", bean.userFirstName);
+ assertEquals("Spengler", bean.userLastName);
+ assertEquals("32", bean.userAge);
+
+ }
}