@JsonValue allows annotated field or getter method to be used as a single value for object serialization. This overrides the usual method of showing properties as JSON output in serialization.
In a class, only one field or getter method should be annotated using @JsonValue. If this annotation is found more than once, an exception will be thrown. If it is applied to a getter method, the method should have a return type and should not take any arguments.
Without using the @JsonValue annotation
Let’s first see an example without using the @JsonValue annotation so that we can visualize the results better after using the @JsonValue annotation.
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Person {
private String firstName;
private String lastName;
private int age;
public Person() {
super();
}
public Person(String firstName, String lastName, int age) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + ", getFirstName()="
+ getFirstName() + ", getLastName()=" + getLastName() + ", getAge()=" + getAge() + "]";
}
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setFirstName("Codekru");
person.setLastName("Programming");
person.setAge(20);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person)); // serializing object
}
}
Output –
{
"firstName" : "Codekru",
"lastName" : "Programming",
"age" : 20
}
With @JsonValue annotation
And now, we have used the @JsonValue annotation at the toString() method. So if we serialize the Person’s object, it will use the toString() method for JSON output during serialization.
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Person {
private String firstName;
private String lastName;
private int age;
public Person() {
super();
}
public Person(String firstName, String lastName, int age) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@JsonValue
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + ", getFirstName()="
+ getFirstName() + ", getLastName()=" + getLastName() + ", getAge()=" + getAge() + "]";
}
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setFirstName("Codekru");
person.setLastName("Programming");
person.setAge(20);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person)); // serializing object
}
}
Output:
"Person [firstName=Codekru, lastName=Programming, age=20, getFirstName()=Codekru, getLastName()=Programming, getAge()=20]"
So we can see in the output it has used the toString method for object serialization. We can also apply @JsonValue annotation at a single field too.
Multiple @JsonValue annotations in the same class
If we use multiple @JsonValue annotations in the same class, it will throw an exception. In the below example, we have used the @JsonValue annotation on the firstName field and the toString() method.
package com.codekru.model;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Person {
@JsonValue
private String firstName;
private String lastName;
private int age;
// constructors and getter-setters
@JsonValue
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + ", getFirstName()="
+ getFirstName() + ", getLastName()=" + getLastName() + ", getAge()=" + getAge() + "]";
}
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setFirstName("Codekru");
person.setLastName("Programming");
person.setAge(20);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person)); // serializing object
}
}
Output:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Problem with definition of [AnnotedClass Test.Person]: Multiple 'as-value' properties defined ([field Test.Person#firstName] vs [method Test.Person#toString(0 params)])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:295)
at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1309)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1427)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:521)
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:799)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:308)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1513)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1215)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1085)
References: https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonValue.html
We hope that you have liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at admin@codekru.com.
Other Jackson Annotations –
- @JsonIgnoreProperties and @JsonIgnore annotations
- @JsonPropertyOrder Jackson Annotation
- @JsonProperty Jackson Annotation
- @JsonRawValue Jackson Annotation
- @JsonAnyGetter Jackson Annotation
- @JsonAnySetter Jackson Annotation
- Java Optional with Jackson
- @JsonInclude Jackson Annotation
- @JsonFormat Jackson Annotation