Spring Boot Tutorial (4) : Disable and customize the default error page

Using @jsonComponent in Spring Boot

1. An overview of the

This tutorial will focus on using the @JsonComponent annotation in Spring Boot.

By using this annotation, we can expose a class as Serializer and Deserializer for Jackson without manually referencing the ObjectMapper object.

Since this is a Spring Boot capability, we don’t need to add additional dependencies and can use it directly in Spring Boot programs.

2. The serialization

Let’s start with the following User object, which contains a User’s favorite color:

public class User {
    private Color favoriteColor;
 
    // standard getters/constructors
}
Copy the code

If we serialized the above object using Jackson, we would 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}}Copy the code

To make the output JSON more readable, we need to output a color in RGB format, such as a color that can be used in CSS.

To do this, we need to create an implementation class for 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); }}Copy the code

Using the serializer above should output JSON like this:

{"favoriteColor":"#f0f8ff"}
Copy the code

The serializer is automatically injected by Spring Boot into ObjectMapper due to the @jsonComponent annotation. We use Junit to write a unit test:

@JsonTest
@RunWith(SpringRunner.class)
public class UserJsonSerializerTest {
 
    @Autowired
    private ObjectMapper objectMapper;
 
    @Test
    public void testSerialization(a) throws JsonProcessingException {
        User user = new User(Color.ALICEBLUE);
        String json = objectMapper.writeValueAsString(user);
  
        assertEquals("{\"favoriteColor\":\"#f0f8ff\"}", json); }}Copy the code

Deserializer will convert a # XXXXXX Color 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 newUser(Color.web(favoriteColor.asText())); }}Copy the code

4. Combine Serializer and Deserializer together

If necessary, serializer and Deserializer can be combined into a single class using an internal class. In this case, we simply add @jsonComponent to the outermost 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 newUser(Color.web(favoriteColor.asText())); }}}Copy the code

5. To summarize

In this tutorial, you can quickly add Serializer and Deserializer for Jackson to your Spring Boot application using the @jsonComponent annotation.

The code snippet for this tutorial can be found on GitHub.