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
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
- How to parse JSON using Gson?
- How to validate JSON in Java using Jackson API
- 5 JSON parsing libraries Java Developers Should Know
- 20 JSON Interview Questions with Answers
- How to parse a JSON array in Java?
- 3 Ways to parse JSON in Java using Jackson and Gson
- How to convert JSON to HashMap in Java?
- How to iterate over JSONObject in Json-simple
- 10 Things Java developers should learn
- How to format JSON String in Java?
- How to escape JSON String in Eclipse
- How to ignore unknown properties while parsing JSON in Java?
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.