Sunday, April 23, 2023

How to use @JsonCreator and @JsonPropertOrder Jackson JN Annotation in Java? Examples

Hello guys, if you are dealing with JSON in Java then you may have come across Jackson, one of the popular JSON library in Java. Jackson provides many cool annotations to serialize and de-serialize JSON to Java object and vice-versa. Earlier, I have showed you 3 ways to convert JSON to Java object and 10 free Jon Tools for programmers and in this article, we will deep dive into two popular Jackson annotations @JsonCreator, @JsonProperty, and @JsonProperOrder. But, Before I tach you exactly how you can use the @JsonCreator annotation, let me briefly tell you a bit more about what Java really is.  
For those of you who don't know, Java is basically a general-purpose, class-based, object-oriented programming language that aims to have lesser implementation dependencies. You can also think of Java as a computing platform for application development. 

What sets Java apart is that it has huge eco-system of libraries which makes it doing anything and everything possible in Java. For example, this Jackson library makes it really easy to produce and consume JSON messages from Java. 


How to Use The @JsonCreator Annotation Along With Examples

In very simple terms, @JsonCreator can be used for fine-tuning the constructors or the factory methods that are used in deserialization. You will also be able to achieve similar results by using the @JsonProperty annotation. 

In this article, I will show you how you can match JSON with a different format for a specific class. This can be done by defining the necessary property names.


@JsonCreator Jackson Annotation Example in Java

Here is our complete Java program you can run to learn how @JsonCreator annotation work and you can use to create object from JSON configuration or JSON files

import java.io.IOException; 

import java.text.ParseException; 



import com.fasterxml.jackson.annotation.JsonCreator; 

import com.fasterxml.jackson.annotation.JsonProperty; 

import com.fasterxml.jackson.databind.ObjectMapper; 



public class JacksonTester {

   public static void main(String args[]) throws ParseException{ 

      String json = "{\"id\":1,\"theName\":\"Mark\"}"; 

      ObjectMapper mapper = new ObjectMapper();    

      try {

         Student student = mapper 

            .readerFor(Student.class) 

            .readValue(json); 

         System.out.println(student.rollNo +", " + student.name); 

      }

      catch (IOException e) { 

         e.printStackTrace(); 

      }

   }

}

class Student {

   public String name; 

   public int rollNo; 


   @JsonCreator 

   public Student(@JsonProperty("theName") String name, @JsonProperty("id") int rollNo){

      this.name = name; 

      this.rollNo = rollNo; 

   }

}


Output

If you run this program, you will get the following output:

1, Mark 


How to use @JsonCreator and @JsonPropertOrder Jackson JN Annotation in Java? Examples


Now, let us see another example. Let us imagine that you are looking to serialize the following JSON:

{
    "id":1,

    "theName":"My bean"
}


You can do this by using either the @JsonCreator annotation or the @JsonProperty annotation. See the following example:


public class BeanWithCreator {

    public int id;

    public String name;



    @JsonCreator

    public BeanWithCreator(

      @JsonProperty("id") int id, 

      @JsonProperty("theName") String name) {

        this.id = id;

        this.name = name;

    }

}



@Test

public void whenDeserializingUsingJsonCreator_thenCorrect()

  throws IOException {

 

    String json = "{\"id\":1,\"theName\":\"My bean\"}";



    BeanWithCreator bean = new ObjectMapper()

      .readerFor(BeanWithCreator.class)

      .readValue(json);

    assertEquals("My bean", bean.name);

}


In addition to @JsonCreator, there are a lot of other Jackson annotations that will make your programming easier. Let us look at a few of them.

The @JsonAnyGetter annotation will give you the flexibility of using a Map field just like standard properties. Check out the following example:


public class ExtendableBean {

    public String name;

    private Map<String, String> properties;



    @JsonAnyGetter

    public Map<String, String> getProperties() {

        return properties;

    }

}



{

    "name":"My bean",

    "attr2":"val2",

    "attr1":"val1"

}



@Test

public void whenSerializingUsingJsonAnyGetter_thenCorrect()

  throws JsonProcessingException {


    ExtendableBean bean = new ExtendableBean("My bean");

    bean.add("attr1", "val1");

    bean.add("attr2", "val2");


    String result = new ObjectMapper().writeValueAsString(bean);


    assertThat(result, containsString("attr1"));

    assertThat(result, containsString("val1"));

}


The @JsonGetter annotation can act as an efficient alternative for the @JsonProperty annotation. See the following example to get a better understanding:

public class MyBean {

    public int id;

    private String name;



    @JsonGetter("name")

    public String getTheName() {

        return name;

    }

}



@Test

public void whenSerializingUsingJsonGetter_thenCorrect()

  throws JsonProcessingException {

 
    MyBean bean = new MyBean(1, "My bean");


    String result = new ObjectMapper().writeValueAsString(bean);


    assertThat(result, containsString("My bean"));

    assertThat(result, containsString("1"));

}


As the name suggests, the @JsonPropertOrder annotation can be used for specifying the order of properties with regard to serialization. See the following example:


@JsonPropertyOrder({ "name", "id" })

public class MyBean {

    public int id;

    public String name;

}


You will get an output like this:

{

    "name":"My bean",

    "id":1

}


Now we can run a simple test:


@Test

public void whenSerializingUsingJsonPropertyOrder_thenCorrect()

  throws JsonProcessingException {


    MyBean bean = new MyBean(1, "My bean");


    String result = new ObjectMapper().writeValueAsString(bean);

    assertThat(result, containsString("My bean"));

    assertThat(result, containsString("1"));

}

The serialization output will be like this:

{

    "id":1,

    "name":"My bean"

}

You can also use the @JsoRawValue annotation for ordering Jackson to serialize a property exactly as it is. Check out the following example:


public class RawBean {

    public String name;


    @JsonRawValue

    public String json;

}


The output of serializing will be like this:

{

    "name":"My bean",

    "json":{

        "attr":false

    }

}


Next, we will run a simple test:


@Test

public void whenSerializingUsingJsonRawValue_thenCorrect()

  throws JsonProcessingException {


    RawBean bean = new RawBean("My bean", "{\"attr\":false}");


    String result = new ObjectMapper().writeValueAsString(bean);

    assertThat(result, containsString("My bean"));

    assertThat(result, containsString("{\"attr\":false}"));

}


The @JsonValue annotation can be used for indicating a specific method that can be used by the library for serializing the whole instance. See the following example to gain a better understanding:


public enum TypeEnumWithValue {

    TYPE1(1, "Type A"), TYPE2(2, "Type 2");



    private Integer id;

    private String name;



    // standard constructors



    @JsonValue

    public String getName() {

        return name;

    }

}



@Test

public void whenSerializingUsingJsonValue_thenCorrect()

  throws JsonParseException, IOException {

 
    String enumAsString = new ObjectMapper()

      .writeValueAsString(TypeEnumWithValue.TYPE1);



    assertThat(enumAsString, is(""Type A""));

}

If wrapping is enabled, the @JsonRootName annotation can be used for specifying the name of the root wrapper that is to be used. Check out the given example:


{

    "id": 1,

    "name": "John"

}


If it is wrapped, it will probably look like this:


{

    "User": {

        "id": 1,

        "name": "John"

    }

}


Now, see this example:


@JsonRootName(value = "user")

public class UserWithRoot {

    public int id;

    public String name;

}



@Test

public void whenSerializingUsingJsonRootName_thenCorrect()

  throws JsonProcessingException {


    UserWithRoot user = new User(1, "John");


    ObjectMapper mapper = new ObjectMapper();

    mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);

    String result = mapper.writeValueAsString(user);



    assertThat(result, containsString("John"));

    assertThat(result, containsString("user"));

}


The output of the serialization will be like this:

{

    "user":{

        "id":1,

        "name":"John"

    }

}


That's all about how to use Jackson annotations to serialize and deserialize JSON in Java. We have seen examples of @JsonCreator, @JsonPropertOrder, @JSonValue, and many other useful Jackson annotation in Java. 

If you liked this article on how to use the @JsonCreator annotation, feel free to share it with your friends and family. I have no doubt that the interfaces in this list will transform you from a complete beginner to a Java expert within a matter of weeks or months. 

Other JSON tutorials in Java you may like


Thanks for reading this article so far. If you like this Java JSON tutorial using Jackson API then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

There are a wide variety of examples in this list that will be beneficial to both absolute beginners as well as intermediate-level learners. You can also drop a comment if you have any doubts and we will get back to you as soon as possible. 

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.