When is the @JsonProperty property used and what is it used for?

JavaAjaxJackson

Java Problem Overview


This bean 'State' :

public class State {
	
	private boolean isSet;

	@JsonProperty("isSet")
	public boolean isSet() {
		return isSet;
	}

	@JsonProperty("isSet")
	public void setSet(boolean isSet) {
		this.isSet = isSet;
	}

}

is sent over the wire using the ajax ' success' callback :

		success : function(response) {	
			if(response.State.isSet){	
				alert('success called successfully)
			}
			

Is the annotation @JsonProperty required here ? What is the advantage of using it ? I think I can remove this annotation without causing any side effects.

Reading about this annotion on https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations I don't know when this is required to be used ?

Java Solutions


Solution 1 - Java

Here's a good example. I use it to rename the variable because the JSON is coming from a .Net environment where properties start with an upper-case letter.

public class Parameter {
  @JsonProperty("Name")
  public String name;
  @JsonProperty("Value")
  public String value; 
}

This correctly parses to/from the JSON:

"Parameter":{
  "Name":"Parameter-Name",
  "Value":"Parameter-Value"
}

Solution 2 - Java

I think OldCurmudgeon and StaxMan are both correct but here is one sentence answer with simple example for you.

@JsonProperty(name), tells Jackson ObjectMapper to map the JSON property name to the annotated Java field's name.

//example of json that is submitted 
"Car":{
  "Type":"Ferrari",
}

//where it gets mapped 
public static class Car {
  @JsonProperty("Type")
  public String type;
 }

Solution 3 - Java

well for what its worth now... JsonProperty is ALSO used to specify getter and setter methods for the variable apart from usual serialization and deserialization. For example suppose you have a payload like this:

{
  "check": true
}

and a Deserializer class:

public class Check {

  @JsonProperty("check")    // It is needed else Jackson will look got getCheck method and will fail
  private Boolean check;

  public Boolean isCheck() {
     return check;
  }
}

Then in this case JsonProperty annotation is neeeded. However if you also have a method in the class

public class Check {

  //@JsonProperty("check")    Not needed anymore
  private Boolean check;

  public Boolean getCheck() {
     return check;
  }
}

Have a look at this documentation too: http://fasterxml.github.io/jackson-annotations/javadoc/2.3.0/com/fasterxml/jackson/annotation/JsonProperty.html

Solution 4 - Java

Without annotations, inferred property name (to match from JSON) would be "set", and not -- as seems to be the intent -- "isSet". This is because as per Java Beans specification, methods of form "isXxx" and "setXxx" are taken to mean that there is logical property "xxx" to manage.

Solution 5 - Java

As you know, this is all about serialize and desalinize an object. Suppose there is an object:

public class Parameter {
  public String _name;
  public String _value; 
}

The serialization of this object is:

{
  "_name": "...",
  "_value": "..."
}

The name of variable is directly used to serialize data. If you are about to remove system api from system implementation, in some cases, you have to rename variable in serialization/deserialization. @JsonProperty is a meta data to tell serializer how to serial object. It is used to:

  • variable name
  • access (READ, WRITE)
  • default value
  • required/optional

from example:

public class Parameter {
  @JsonProperty(
        value="Name",
        required=true,
        defaultValue="No name",
        access= Access.READ_WRITE)
  public String _name;
  @JsonProperty(
        value="Value",
        required=true,
        defaultValue="Empty",
        access= Access.READ_WRITE)
  public String _value; 
}

Solution 6 - Java

Adding the JsonProperty also ensures safety in case someone decides they want to change one of the property names not realizing the class in question will be serialized to a Json object. If they change the property name the JsonProperty ensures it will be used in the Json object, and not the property name.

Solution 7 - Java

In addition to all the answers above, don't forget the part of the documentation that says

> Marker annotation that can be used to define a non-static method as a > "setter" or "getter" for a logical property (depending on its > signature), or non-static object field to be used (serialized, > deserialized) as a logical property.

If you have a non-static method in your class that is not a conventional getter or setter then you can make it act like a getter and setter by using the annotation on it. See the example below

public class Testing {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getIdAndUsername() {
        return id + "." + username; 
    }
    
    public String concatenateIdAndUsername() {
        return id + "." + username; 
    }
}

When the above object is serialized, then response will contain

  • username from getUsername()
  • id from getId()
  • idAndUsername from getIdAndUsername*

Since the method getIdAndUsername starts with get then it's treated as normal getter hence, why you could annotate such with @JsonIgnore.

If you have noticed the concatenateIdAndUsername is not returned and that's because it name does not start with get and if you wish the result of that method to be included in the response then you can use @JsonProperty("...") and it would be treated as normal getter/setter as mentioned in the above highlighted documentation.

Solution 8 - Java

As addition to other answers, @JsonProperty annotation is really important if you use the @JsonCreator annotation in classes which do not have a no-arg constructor.

public class ClassToSerialize {

	public enum MyEnum {
		FIRST,SECOND,THIRD
	}

	public String stringValue = "ABCD";
	public MyEnum myEnum;


	@JsonCreator
	public ClassToSerialize(MyEnum myEnum) {
		this.myEnum = myEnum;
	}

	public static void main(String[] args) throws IOException {
		ObjectMapper mapper = new ObjectMapper();

		ClassToSerialize classToSerialize = new ClassToSerialize(MyEnum.FIRST);
		String jsonString = mapper.writeValueAsString(classToSerialize);
		System.out.println(jsonString);
		ClassToSerialize deserialized = mapper.readValue(jsonString, ClassToSerialize.class);
		System.out.println("StringValue: " + deserialized.stringValue);
        System.out.println("MyEnum: " + deserialized.myEnum);
	}
}

In this example the only constructor is marked as @JsonCreator, therefore Jackson will use this constructor to create the instance. But the output is like:

> Serialized: {"stringValue":"ABCD","myEnum":"FIRST"}

> Exception in > thread "main" > com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not > construct instance of > ClassToSerialize$MyEnum > from String value 'stringValue': value not one of declared Enum > instance names: [FIRST, SECOND, THIRD]

But after the addition of the @JsonProperty annotation in the constructor:

@JsonCreator
public ClassToSerialize(@JsonProperty("myEnum") MyEnum myEnum) {
    this.myEnum = myEnum;
}

The deserialization is successful:

> Serialized: {"myEnum":"FIRST","stringValue":"ABCD"} > > StringValue: ABCD

> MyEnum: FIRST

Solution 9 - Java

From JsonProperty javadoc,

> Defines name of the logical property, i.e. JSON object field name to use for the property. If value is empty String (which is the default), will try to use name of the field that is annotated.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionblue-skyView Question on Stackoverflow
Solution 1 - JavaOldCurmudgeonView Answer on Stackoverflow
Solution 2 - JavagrepitView Answer on Stackoverflow
Solution 3 - JavaRicheekView Answer on Stackoverflow
Solution 4 - JavaStaxManView Answer on Stackoverflow
Solution 5 - JavaMostafaView Answer on Stackoverflow
Solution 6 - Javaarush436View Answer on Stackoverflow
Solution 7 - JavaRafView Answer on Stackoverflow
Solution 8 - JavaDVargaView Answer on Stackoverflow
Solution 9 - Javasc30View Answer on Stackoverflow