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.





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.:… Read more »
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 »
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”)
@Sudhir yes, you can use annotation `@JsonNaming` to specify per-type naming convention (add it to class in question)
Thanks,
Good article for domain model which are generated and you can’t modify the source.