Partner – Microsoft – NPI (cat= Spring Boot)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

Course – LS (cat=JSON/Jackson)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

This quick article is focused on how to use the @JsonComponent annotation in Spring Boot.

The annotation allows us to expose an annotated class to be a Jackson serializer and/or deserializer without the need to add it to the ObjectMapper manually.

This is part of the core Spring Boot module, so there are no additional dependencies required in a plain Spring Boot application.

2. Serialization

Let’s start with the following User object containing a favorite color:

public class User {
    private Color favoriteColor;

    // standard getters/constructors
}

If we serialize this object using Jackson with default settings we get:

{
  "favoriteColor": {
    "red": 0.9411764740943909,
    "green": 0.9725490212440491,
    "blue": 1.0,
    "opacity": 1.0,
    "opaque": true,
    "hue": 208.00000000000003,
    "saturation": 0.05882352590560913,
    "brightness": 1.0
  }
}

We can make the JSON a lot more condensed and readable by just printing the RGB values – for example, to be used in CSS.

To this extent, we just have to create a class that implements JsonSerializer:

@JsonComponent
public class UserJsonSerializer extends JsonSerializer<User> {

    @Override
    public void serialize(User user, JsonGenerator jsonGenerator, 
      SerializerProvider serializerProvider) throws IOException, 
      JsonProcessingException {
 
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField(
          "favoriteColor", 
          getColorAsWebColor(user.getFavoriteColor()));
        jsonGenerator.writeEndObject();
    }

    private static String getColorAsWebColor(Color color) {
        int r = (int) Math.round(color.getRed() * 255.0);
        int g = (int) Math.round(color.getGreen() * 255.0);
        int b = (int) Math.round(color.getBlue() * 255.0);
        return String.format("#%02x%02x%02x", r, g, b);
    }
}

With this serializer, the resulting JSON has been reduced to:

{"favoriteColor":"#f0f8ff"}

Due to the @JsonComponent annotation, the serializer is registered in the Jackson ObjectMapper in the Spring Boot application. We can test this with the following JUnit test:

@JsonTest
@RunWith(SpringRunner.class)
public class UserJsonSerializerTest {

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    public void testSerialization() throws JsonProcessingException {
        User user = new User(Color.ALICEBLUE);
        String json = objectMapper.writeValueAsString(user);
 
        assertEquals("{\"favoriteColor\":\"#f0f8ff\"}", json);
    }
}

3. Deserialization

Continuing with the same example, we can write a deserializer that will turn the web color String into a JavaFX Color object:

@JsonComponent
public class UserJsonDeserializer extends JsonDeserializer<User> {
 
    @Override
    public User deserialize(JsonParser jsonParser, 
      DeserializationContext deserializationContext) throws IOException, 
      JsonProcessingException {
 
        TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
        TextNode favoriteColor
          = (TextNode) treeNode.get("favoriteColor");
        return new User(Color.web(favoriteColor.asText()));
    }
}

Let’s test the new deserializer and make sure everything works as expected:

@JsonTest
@RunWith(SpringRunner.class)
public class UserJsonDeserializerTest {

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    public void testDeserialize() throws IOException {
        String json = "{\"favoriteColor\":\"#f0f8ff\"}"
        User user = objectMapper.readValue(json, User.class);
 
        assertEquals(Color.ALICEBLUE, user.getFavoriteColor());
    }
}

4. Serializer and Deserializer in One Class

When desired, we can connect the serializer and the deserializer in one class by using two inner classes and adding the @JsonComponent on the enclosing class:

@JsonComponent
public class UserCombinedSerializer {
 
    public static class UserJsonSerializer 
      extends JsonSerializer<User> {

        @Override
        public void serialize(User user, JsonGenerator jsonGenerator, 
          SerializerProvider serializerProvider) throws IOException, 
          JsonProcessingException {
 
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField(
              "favoriteColor", getColorAsWebColor(user.getFavoriteColor()));
            jsonGenerator.writeEndObject();
        }

        private static String getColorAsWebColor(Color color) {
            int r = (int) Math.round(color.getRed() * 255.0);
            int g = (int) Math.round(color.getGreen() * 255.0);
            int b = (int) Math.round(color.getBlue() * 255.0);
            return String.format("#%02x%02x%02x", r, g, b);
        }
    }

    public static class UserJsonDeserializer 
      extends JsonDeserializer<User> {
 
        @Override
        public User deserialize(JsonParser jsonParser, 
          DeserializationContext deserializationContext)
          throws IOException, JsonProcessingException {
 
            TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
            TextNode favoriteColor = (TextNode) treeNode.get(
              "favoriteColor");
            return new User(Color.web(favoriteColor.asText()));
        }
    }
}

5. Conclusion

This quick tutorial showed how to quickly add a Jackson serializer/deserializer in a Spring Boot application by leveraging component scanning with the @JsonComponent annotation.

The code snippets can be found over on GitHub.

Course – LS (cat=JSON/Jackson)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.