Abhishek Somani

About Abhishek Somani

Abhishek is working as a senior java developer in a product start up .He has worked on various java related enterprise applications and frameworks. He loves to explore new technologies

How to Use PropertyNamingStrategy in Jackson

Jackson api is used extensively to convert json to Object and Object to JSON.So if you have a json string and want to convert it in a java object , create field names of bean same as the fields in json. Jackson follows standard bean convention in mapping json fields to java object fields , but if you have a json which does not follow naming conventions [for ex fields starting with capital case] , jackson does not know how to map this fields with your java object . You can use @JsonProperty annotation , but sometimes its hard to put this annotation on every field of every class .That’s where PropertyNamingStrategy comes in to picture . You can modify this class according to your needs.
 
 
Let’s take an example. We have a json like this :

{'CustName':'Abhishek Somani','Result':null,'CustNo':'1234'}

Note here , firs letter of every field is capital letter , which is not the standard bean naming convention. And we are trying to map this json to following bean :

public class JsonBean {
 /**
  * 
  */

 private String custNo ;
 private String custName ; 
 private String result;

 public String getResult() {
  return result;
 }
 public void setResult(String result) {
  this.result = result;
 }
 public String getCustNo() {
  return custNo;
 }
 public void setCustNo(String custNo) {
  this.custNo = custNo;
 }
 public String getCustName() {
  return custName;
 }
 public void setCustEm(String custName) {
  this.custName = custName;
 }
}

To map this json to jsonBean , we have to create our own custom naming strategy like this. Here We are converting first letter of the field name to upper case.

import org.codehaus.jackson.map.MapperConfig;
import org.codehaus.jackson.map.PropertyNamingStrategy;
import org.codehaus.jackson.map.introspect.AnnotatedField;
import org.codehaus.jackson.map.introspect.AnnotatedMethod;

public class MyNameStrategy extends PropertyNamingStrategy
 {
  @Override
  public String nameForField(MapperConfig
                       config,
   AnnotatedField field, String defaultName) {
     return convert(defaultName);

  }
  @Override
  public String nameForGetterMethod(MapperConfig
                       config,
   AnnotatedMethod method, String defaultName) {
     return convert(defaultName);
  }

  @Override
  public String nameForSetterMethod(MapperConfig
                       config,
    AnnotatedMethod method, String defaultName) {
   String a = convert(defaultName); 
   return a;
  }

  public String convert(String defaultName )
  {
   char[] arr = defaultName.toCharArray();
   if(arr.length !=0)
   {
    if ( Character.isLowerCase(arr[0])){
     char upper = Character.toUpperCase(arr[0]);
     arr[0] = upper;
    }
   }
   return new StringBuilder().append(arr).toString();
  }

 }

This is the main class to test . We are setting our customNamingStrategy in ObjectMapper of Jackson.

import java.io.File;
import java.io.IOException;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class JsonTest {

 public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
  ObjectMapper mapper = new ObjectMapper();
  mapper.setPropertyNamingStrategy(new MyNameStrategy());
  File f = new File('F:/abc.json');
  JsonBean bean = (JsonBean)mapper.readValue(f, JsonBean.class);

  mapper.writeValue(new File('F:/abc1.json'),bean);

  System.out.println(bean.getCustEm());
 }

}

If you fail to provide a naming strategy , you will get Exception like this :

Exception in thread 'main' org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field 'CustNo' (Class JsonBean), not marked as ignorable

 

Reference: How to Use PropertyNamingStrategy in Jackson from our JCG partner Abhishek Somani at the Java , J2EE , Server blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

7 Responses to "How to Use PropertyNamingStrategy in Jackson"

  1. Sudhir Ravindramohan says:

    Is it possible to use json/bean specific PropertyNamingStrategies. In the example above, it seems to be global at the ObjectMapper level.

    • somani says:

      for bean level ..you can use @jsonProperty annotation for every specific field on bean ..

      • Swarup says:

        I have a bean like :
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlRootElement (name= “notification”)
        public class NotificationBean {
        @XmlElement
        public String subject;
        @XmlElement
        public String content;
        @XmlElement
        public String recipient;
        }

        in controller I am using this bean as:

        @POST
        @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
        public Response addNotification(
        @PathParam(NotificationConstants.API_VERSION_REF) final ApiVersionParam versionRef,
        @PathParam(NotificationConstants.CUSTOMER_REF) final CustomerParam customerRef,
        final NotificationBean notification) throws WebApplicationException,
        NotificationServerException {

        using Advanced Rest CLient I am passing below JSON as payload when my content type is application/json

        {
        “subject”:”Test_Subject”,
        “content”: “Test Content”,
        “recipient”: “Test Recipient”
        }

        and these values are accessible in controller. But when I am passing the below json it gives error. [N.B.: I have made some/all fields first letter capital]
        {
        “Subject”:”Test_Subject”,
        “Content”: “Test Content”,
        “recipient”: “Test Recipient”
        }

        Are there any way, so that I can accept this property also in controller. In other words I want to make the bean property as case insensitive.
        Please reply

      • Swarup says:

        I have a bean like :
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlRootElement (name= “notification”)
        public class NotificationBean {
        @XmlElement
        public String subject;
        @XmlElement
        public String content;
        @XmlElement
        public String recipient;
        }
        in controller I am using this bean as:
        @POST
        @Consumes({MediaType.APPLICATION_JSON,MediaType.AP PLICATION_XML})
        public Response addNotification(
        @PathParam(NotificationConstants.API_VERSION_REF) final ApiVersionParam versionRef,
        @PathParam(NotificationConstants.CUSTOMER_REF) final CustomerParam customerRef,
        final NotificationBean notification) throws WebApplicationException,
        NotificationServerException {
        using Advanced Rest CLient I am passing below JSON as payload when my content type is application/json
        {
        “subject”:”Test_Subject”,
        “content”: “Test Content”,
        “recipient”: “Test Recipient”
        }
        and these values are accessible in controller. But when I am passing the below json it gives error. [N.B.: I have made some/all fields first letter capital]
        {
        “Subject”:”Test_Subject”,
        “Content”: “Test Content”,
        “recipient”: “Test Recipient”
        }
        Are there any way, so that I can accept this property also in controller. In other words I want to make the bean property as case insensitive.
        Please reply

  2. Note too that Jackson 2.x comes with two default implementations for commonly encountered “non-Java” naming conventions:

    * PropertyNamingStrategy.PascalCaseStrategy (“FirstName”)
    * PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy (“first_name”)

  3. @Sudhir yes, you can use annotation `@JsonNaming` to specify per-type naming convention (add it to class in question)

  4. Dave L says:

    Thanks,
    Good article for domain model which are generated and you can’t modify the source.

Leave a Reply


+ one = 2



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close