From da579e3da706dd2429b90b3d5d35fc62f5bde7f4 Mon Sep 17 00:00:00 2001 From: David Haraburda Date: Thu, 3 Sep 2015 13:55:58 -0500 Subject: [PATCH 1/2] Add mapper feature to allow explicitly named properties to be renamed with PropertyNamingStrategy --- .../jackson/databind/MapperFeature.java | 11 ++++++ .../introspect/POJOPropertiesCollector.java | 5 ++- .../introspect/TestNamingStrategyStd.java | 38 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) 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..e3c36075f5 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 test2() 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); + + } } From b6a26b93ef58807df18e08f2253a90ea4b86a5a1 Mon Sep 17 00:00:00 2001 From: David Haraburda Date: Thu, 3 Sep 2015 14:10:01 -0500 Subject: [PATCH 2/2] fix test name --- .../jackson/databind/introspect/TestNamingStrategyStd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e3c36075f5..96be4a6d28 100644 --- a/src/test/java/com/fasterxml/jackson/databind/introspect/TestNamingStrategyStd.java +++ b/src/test/java/com/fasterxml/jackson/databind/introspect/TestNamingStrategyStd.java @@ -327,7 +327,7 @@ static class ExplicitBean { String userAge = "35"; } - public void test2() throws Exception { + 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);