Jackson 1.8: custom property naming strategies
One of big goals for Jackson 1.8 is to implement oldest open feature requests. One such feature is ability to customize property naming strategy: that is, to allow use of JSON names that do not match requirements of Bean naming conventions.
For example, consider case of Twitter JSON API, which uses "C-style"
naming convention, so what would be "profileImageUrl" with bean naming
convention, is instead "profile_image_url".
With earlier
Jackson versions, one has had to annotate all properties with
@JsonProperty annotation; or use rather unwieldy method names like
"getprofile_image_url()" (which would work, just look ugly).
But version 1.8 will finally allow use of custom naming strategies. Let's examine how.
First thing to do is to extend org.codehaus.jackson.map.PropertyNamingStrategy
static class CStyleStrategy extends PropertyNamingStrategy { public String nameForField(MapperConfig?> config, AnnotatedField field, String defaultName) {
return convert(defaultName); } public String nameForGetterMethod(MapperConfig?> config, AnnotatedMethod method, String defaultName) { return convert(defaultName); } public String nameForSetterMethod(MapperConfig?> config, AnnotatedMethod method, String defaultName) { return convert(defaultName); } private String convert(String input) { // easy: replace capital letters with underscore, lower-cases equivalent StringBuilder result = new StringBuilder(); for (int i = 0, len = input.length(); i < len; ++i) { char c = input.charAt(i); if (Character.isUpperCase(c)) { result.append('_'); c = Character.toLowerCase(c); } result.append(c); } return result.toString(); } }
which in this case will just convert property names by replacing all
capital letters with underscore followed by lower-cased version of the
letter.
And then the only other thing is to register this strategy
with ObjectMapper:
ObjectMapper mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(new PrefixStrategy());
and after this we could do:
static class PersonBean { public String firstName; public String lastName; public PersonBean(String f, String l) { firstName = f; lastName = l; } } // so this would hold true: assertEquals("{\"first_name\":\"Joe\",\"last_name\":\"Sixpack\"}", new PersonBean("Joe", "Sixpack"));
This should help working with APIs that use C-style underscore notation, or variation of camel casing (such as one where first word is also capitalized).