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.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

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


9 − five =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books