Home » Java » Enterprise Java » How to Use PropertyNamingStrategy in Jackson

About Abhishek Somani

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 our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

7 comments

  1. Sudhir Ravindramohan

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

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

      • 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

      • 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. Thanks,
    Good article for domain model which are generated and you can’t modify the source.

Leave a Reply

Your email address will not be published. Required fields are marked *

*


+ eight = 14

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Do you want to know how to develop your skillset and become a ...

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!
Get ready to Rock!
To download the books, please verify your email address by following the instructions found on the email we just sent you.

THANK YOU!

Close