Enterprise Java

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.

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
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sudhir Ravindramohan
Sudhir Ravindramohan
11 years ago

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

somani
11 years ago

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

Swarup
Swarup
11 years ago
Reply to  somani

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.:… Read more »

Swarup
Swarup
11 years ago
Reply to  somani

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.… Read more »

Cowtowncoder
11 years ago

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

Cowtowncoder
11 years ago

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

Dave L
Dave L
11 years ago

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

Back to top button