Friday, March 11, 2011

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).

blog comments powered by Disqus

Sponsored By


Related Blogs

(by Author (topics))

Powered By

About me

  • I am known as Cowtowncoder
  • Contact me at@yahoo.com
Check my profile to learn more.