In this tutorial we will learn how to produce and consume JSON data in a Spring Boot applications using the built-in Jackson provider.
What is Jackson?
Jackson is a Java library for handling JSON data. It provides a set of tools for parsing, generating, and manipulating JSON data in Java applications. Jackson is widely used in the Java ecosystem, including in popular frameworks like Spring Boot.
Using Jackson in a Spring Boot project
Let’s see an example application which uses Jackson to manipulate some data. Consider the following Spring Boot Controller class:
@RestController public class CustomerController { @Autowired CustomerRepository repository; @RequestMapping("/list") public List<Customer> findAll() { return repository.getData(); } @RequestMapping("/one/{id}") public Customer findOne(@PathVariable int id) { return repository.getData().get(id); } }
Assumed that the Customer object is created in the following way:
@Component public class CustomerRepository { List < Customer > customerList = new ArrayList < Customer > (); @PostConstruct public void init() { try { customerList.add(new Customer(1, "frank"); customerList.add(new Customer(2, "john"); } catch (ParseException e) { e.printStackTrace(); } } public List < Customer > getData() { return customerList; } }
Then, when requesting the URL http://localhost:8080/list the following JSON data will be returned:
[ { "id":1, "name":"frank" }, { "id":2, "name":"john" } ]
There is no need to add any jackson-core,jackson-annotations and jackson-databind as their jars are automatically added by Spring Boot:
jar tvf demo-rest-0.0.1-SNAPSHOT.jar . . . . 1348389 Tue Aug 06 01:41:54 CEST 2019 BOOT-INF/lib/jackson-databind-2.9.9.3.jar 66519 Sat Jul 29 20:53:26 CEST 2017 BOOT-INF/lib/jackson-annotations-2.9.0.jar 325632 Wed May 15 19:58:38 CEST 2019 BOOT-INF/lib/jackson-core-2.9.9.jar 33429 Thu May 16 03:26:48 CEST 2019 BOOT-INF/lib/jackson-datatype-jdk8-2.9.9.jar 100674 Thu May 16 03:27:12 CEST 2019 BOOT-INF/lib/jackson-datatype-jsr310-2.9.9.jar 8645 Thu May 16 03:26:28 CEST 2019 BOOT-INF/lib/jackson-module-parameter-names-2.9.9.jar
Using Jackson annotations
In the first example, we were using the efault Jackson serialization/deserialization. Therefore there was no need to add any extra dependency. On the other hand, if you want to use Jackson annotations in your code, to compile the application it is required to add a Jackson dependency.
Let’s create a more complex Customer object:
package com.example.testrest; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.Date; public class Customer { @JsonIgnore private int id; @JsonProperty("customer_name") private String name; @JsonSerialize(using = CustomDateSerializer.class) public Date birthDate; public Customer(int id, String name, Date birthDate) { this.id = id; this.name = name; this.birthDate = birthDate; } // Getter/Setter omitted for brevity }
This class contains the following annotations:
- @com.fasterxml.jackson.annotation.JsonIgnore: This annotation indicates that the property is to be ignored by introspection-based serialization and deserialization functionality.
- @com.fasterxml.jackson.annotation.JsonProperty: This annotation can be used to provide a custom name field name in JSON objects
- @com.fasterxml.jackson.databind.annotation.JsonSerialize: This annotation can be used to provide a custom Java class to serialize the content of JSON object.
package com.example.testrest; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class CustomDateSerializer extends StdSerializer<Date> { private static SimpleDateFormat formatter = new SimpleDateFormat("EEEEE MMMMM yyyy"); public CustomDateSerializer() { this(null); } public CustomDateSerializer(Class<Date> t) { super(t); } @Override public void serialize( Date value, JsonGenerator gen, SerializerProvider arg2) throws IOException, JsonProcessingException { gen.writeString(formatter.format(value)); } }
In the new example, we will include the extra Date field will be included in the Constructor of the Customer class:
@PostConstruct public void init() { try { customerList.add(new Customer(1, "frank", new SimpleDateFormat("dd/MM/yyyy").parse("17/10/1970"))); customerList.add(new Customer(2, "john", new SimpleDateFormat("dd/MM/yyyy").parse("25/07/1980"))); } catch (ParseException e) { e.printStackTrace(); } }
The result of (http://localhost:8080/list), will be the following JSON data:
In order to compile your example, you will need to include the following extra dependency:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.14.2</version> </dependency>
Serializing and Deserializing Data
In our example, the RestController was managing the serialization of a Java class in a JSON Media Type. On the other hand, you can also perform serialization and deserialization from your code. Let’s see how.
Serializing Java objects to JSON
To serialize a Java object to JSON using Jackson, you can use the ObjectMapper
class. The ObjectMapper
class provides methods for serializing Java objects to JSON and deserializing JSON data to Java objects.
Here’s an example of how to serialize a Java object to JSON using Jackson:
import com.fasterxml.jackson.databind.ObjectMapper; public class MyObject { private String name; private int age; // getters and setters omitted for brevity public static void main(String[] args) throws Exception { MyObject obj = new MyObject(); obj.setName("John"); obj.setAge(30); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(obj); System.out.println(json); } }
In this example, we’re creating a MyObject
instance, setting its properties, and then using an ObjectMapper
instance to serialize the object to a JSON string. The writeValueAsString()
method of the ObjectMapper
class converts the Java object to a JSON string.
Deserializing JSON to Java objects
To deserialize JSON data to a Java object using Jackson, you can again use the ObjectMapper
class. The ObjectMapper
class provides methods for deserializing JSON data to Java objects.
Here’s an example of how to deserialize a JSON string to a Java object using Jackson:
import com.fasterxml.jackson.databind.ObjectMapper; public class MyObject { private String name; private int age; // getters and setters omitted for brevity public static void main(String[] args) throws Exception { String json = "{\"name\":\"John\",\"age\":30}"; ObjectMapper mapper = new ObjectMapper(); MyObject obj = mapper.readValue(json, MyObject.class); System.out.println(obj.getName()); System.out.println(obj.getAge()); } }
In this example, we’re creating a String
variable containing a JSON string, and then using an ObjectMapper
instance to deserialize the JSON string to a MyObject
instance. The readValue()
method of the ObjectMapper
class converts the JSON data to a Java object.
Conclusion
Jackson is a powerful library for working with JSON data in Java applications. In this tutorial, we’ve seen how to use Jackson in a Spring Boot project to serialize Java objects to JSON and deserialize JSON data to Java objects. With this knowledge, you should be able to work with JSON data in your Spring Boot applications using Jackson.
The source code for this Spring Boot Jackson example is available here: https://github.com/fmarchioni/masterspringboot/tree/master/json/demo-jackson
Found the article helpful? if so please follow us on Socials