@JsonValue Jackson Annotation

@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 [email protected]

Other Jackson Annotations –

Liked the article? Share this on

Leave a Comment

Your email address will not be published.