Java Jackson @JsonDeserialize Example

1. Introduction

Jackson's @JsonDeserialize annotation allows customization of deserialization by specifying a custom deserializer for the annotated field, method, or class. This is useful when dealing with complex data structures, special formatting, or other scenarios where the default deserialization process doesn't yield the desired outcome.

2. Example Steps

1. Create a Product class with a price field represented as a double.

2. Implement a custom deserializer, PriceDeserializer, that parses price in the format $xx.xx and returns its double value.

3. Annotate the price field with @JsonDeserialize to use PriceDeserializer.

4. Deserialize a JSON string containing a product's details with a price in the format $xx.xx.

5. Print the deserialized Product object to verify the price has been correctly deserialized.

3. Java Jackson @JsonDeserialize Example

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class JsonDeserializeExample {

    public static void main(String[] args) throws Exception {
        // Sample JSON input with price in the format $xx.xx
        String json = "{\"productName\":\"Laptop\",\"price\":\"$1000.50\"}";

        // Use Jackson to deserialize the JSON input
        ObjectMapper objectMapper = new ObjectMapper();
        Product product = objectMapper.readValue(json, Product.class);

        // Print the resulting object
        System.out.println(product);
    }

    public static class Product {
        private String productName;

        // Annotate the field with our custom deserializer
        @JsonDeserialize(using = PriceDeserializer.class)
        private double price;

        public String getProductName() {
            return productName;
        }

        public void setProductName(String productName) {
            this.productName = productName;
        }

        public double getPrice() {
            return price;
        }

        public void setPrice(double price) {
            this.price = price;
        }

        @Override
        public String toString() {
            return "Product{productName='" + productName + "', price=" + price + '}';
        }
    }

    // Custom deserializer for the price
    public static class PriceDeserializer extends JsonDeserializer<Double> {

        @Override
        public Double deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String priceString = p.getText();
            // Removing the $ sign and converting the string to double
            return Double.parseDouble(priceString.substring(1));
        }
    }
}

Output:

Product{productName='Laptop', price=1000.5}

4. Step By Step Explanation

In this example, we have a Product class with a price field that is represented as a double. However, the provided JSON string specifies the price in a formatted string with a dollar sign. The default deserialization would fail to correctly parse this value.

To handle this, we've implemented a custom deserializer PriceDeserializer that takes the price string, removes the dollar sign, and converts the remaining value to a double.

The price field in the Product class is annotated with @JsonDeserialize(using = PriceDeserializer.class), which instructs Jackson to use the PriceDeserializer class when deserializing the price field.

During deserialization, Jackson sees the annotation and uses our custom deserializer to convert the formatted price string to its double representation, ensuring that the Product object reflects the actual price value.


Comments