"Hi, Amigo!"

"Hi, Ellie!"

"Since you've already been introduced to JSON, let's talk more about it today."

"OK. Where is it usually used?"

"Here's how it usually works. Someone (the client) requests data from a Java program (the server). The program creates Java objects and fills them with information from the database. It then converts them into a format that the requester (the client) can understand, such as JSON, and sends them back."

"Let me tell you how to work with JSON in Java. Essentially, we only need to do two things: serialize Java objects into the JSON format, and deserialize Java objects from the JSON format."

"In other words, JSON is a standard for sending messages/data from one program to another. There are a lot of standards like that. But if the program is written in JavaScript, it usually tries to use JSON."

"OK. I'm ready."

"Great. Then let's get started."

Serialization into JSON - 1

"As you already know, Java has built-in standard serialization tools. But they don't support JSON. So, if you need to serialize an object into JSON, you can use one of the popular frameworks (libraries) that know how to do this."

"What's the difference between these different frameworks?"

"They usually differ in their level of complexity: there are frameworks that can only do the very basics, but they are very small and simple. And there are large complex frameworks that can do much more."

"Jackson is one of the most popular frameworks. We will use it as an example as we look at how to work with JSON."

"First, you need to download this framework and add it to your project. You need to do this directly in IntelliJ IDEA. You can download the framework using this link."

"Done."

"Great. Let's carry on, then."

"Converting a Java object into JSON is about as easy as serializing it. To do this, there is a special ObjectMapper class (com.fasterxml.jackson.databind.ObjectMapper)."

"Let me show you a working example, and then we'll analyze it:"

Convert an object to JSON"
public static void main(String[] args) throws IOException
{
 // Create an object to be serialized into JSON
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // This is the Jackson object that performs the serialization
 ObjectMapper mapper = new ObjectMapper();

 // And here's the serialization itself: the first argument is where, and the second is what
 mapper.writeValue(writer, cat);

 // Convert everything written to the StringWriter into a String
 String result = writer.toString();
 System.out.println(result);
}
A Cat class whose objects convert to JSON
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;
Cat(){}
}
Serialization result and screen output:
{"name":"Missy", "age":5, "weight":4}

"Here's how it works:"

"In lines 4-7, we create a Cat object and populate it with data."

"In line 10, we create a Writer object where we will write a JSON-string representation of the object."

"In line 13, we create an ObjectMapper object that will perform all of the serialization."

"In line 16, we write the JSON representation of the cat object to writer."

"In lines 19-20, we display the result on the screen."

"Everything looks pretty simple. No harder than native serialization in Java."

"What would deserialization look like?"

"It's almost the same, just shorter:"

Convert an object from JSON
public static void main(String[] args) throws IOException
{
 String jsonString = "{ \"name\":\"Missy\", \"age\":5, \"weight\":4}";
 StringReader reader = new StringReader(jsonString);

 ObjectMapper mapper = new ObjectMapper();

 Cat cat = mapper.readValue(reader, Cat.class);
}
A class whose objects are deserialized from JSON format
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;

 Cat() { }
}

"It's even easier. We take ObjectMapper and pass it a string or a StringReader with JSON, as well as the class of the object to be deserialized. Then we call the readValue method, and as output we get a ready-made Java object with all of the data."

"Well, that's exactly like deserialization in Java."

"Almost. There are several requirements placed on objects serialized into, or deserialized from, JSON:"

"1) the fields must be visible: they must either be public or have getters and setters"

"2) there must be a default constructor (one without parameters)"

"I see. That's not too surprising. But Java serialized everything, even private fields."

"Well, that was Java. It has access to hidden data. You can't hide from yourself."

"There's a third aspect here. I hope you noticed the @JsonAutoDetect annotation on the Cat class?"

"Yep. I was just about to ask what it was."

"It's an annotation: housekeeping information for the Jackson framework. By using the right annotations, you have quite a lot of flexible control over the results of serialization into JSON."

"Cool! What kind of annotations are there?"

"Here are a few examples:"

Annotation Description
@JsonAutoDetect Placed before a class.
Marks a class as ready to be serialized into JSON.
@JsonIgnore Placed before a property.
The property will be ignored during serialization.
@JsonProperty Placed before a property or a getter or setter. Lets you specify a different field name during serialization.
@JsonWriteNullProperties Placed before a class.
Object fields that are null won't be ignored.
@JsonPropertyOrder Placed before a class.
Lets you specify the field order during serialization.

"How interesting! Are there more?"

"There are many. But we won't cover them right now. Now let's rework our first example slightly:"

Convert an object to JSON
public static void main(String[] args) throws IOException
{
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 StringWriter writer = new StringWriter();

 ObjectMapper mapper = new ObjectMapper();

 mapper.writeValue(writer, cat);

 String result = writer.toString();
 System.out.println(result);
}
A class whose objects convert to JSON
@JsonAutoDetect
class Cat
{
 @JsonProperty("alias")
 public String name;
 public int age;
 @JsonIgnore
 public int weight;

 Cat() {
 }
}
Serialization result and screen output:
{"age":5, "alias":"Missy"}

"The code remains the same, but I changed the annotations: I specified another name for the name field: alias. I also marked the weight field as Ignore, which caused the JSON object to change."

"It's good that you can customize everything like that. I think I'll definitely find this useful."

"And deserialization will understand how to work with this? When deserializing from JSON to a Java object, the value of the alias field will be written to the Cat object's name field?"

"Yes, deserialization will work as it should. It's smart."

"What's not to be happy about then."

"Thank you for this interesting lesson, Ellie."