Thursday 21 March 2013

Textual Representation of logo

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


Post comments and share if you like this post!!