JSON class library Jackson elegantly serializes Java enumeration classes

1. Preface

In Java development, in order to avoid too many magic values, we use enumeration classes to encapsulate some static state codes. However, it's not so smooth to return the meaning of these enumerations to the front end correctly and comprehensively. We usually use the Jackson class library to serialize objects into JSON. Today, we'll talk about a general skill about using Jackson to serialize enumerations.

2. General enumeration paradigm

In order to facilitate unified processing and standardize unified style, it is recommended to specify a unified abstract interface, such as:

/**
 * The interface Enumerator.
 */
public interface Enumerator {
    /**
     * Code integer.
     *
     * @return the integer
     */
    Integer code();

    /**
     * Description string.
     *
     * @return the string
     */
    String description();
}

Let's write an implementation to identify gender:

public enum GenderEnum implements Enumerator {
   
    UNKNOWN(0, "unknown"),

    MALE(1, "male"),

    FEMALE(2, "female");


    private final Integer code;
    private final String description;

    GenderEnum(Integer code, String description) {
        this.code = code;
        this.description = description;
    }


    @Override
    public Integer code() {
        return code;
    }

    @Override
    public String description() {
        return description;
    }
}

3. Serialization enumeration

If we use Jackson to serialize the enumeration directly, we can only simply output the String name of the enumeration:

    @Resource
    private ObjectMapper objectMapper;

    @Test
    void enumTest() {
        try {
            String s = objectMapper.writeValueAsString(GenderEnum.MALE);
            // Output string MALE
            System.out.println(s);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

We expect that GenderEnum.MALE Serialize to {"code":1,"description": "man"}. We can customize a Module to ObjectMapper to achieve this personalized requirement:

         // Declare a simple Module object
         SimpleModule module = new SimpleModule();
           // Add a serializer to the Module
            module.addSerializer(Enumerator.class, new JsonSerializer<Enumerator>() {
                @Override
                public void serialize(Enumerator value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                   // Start writing objects
                    gen.writeStartObject();
                    // Specify k V code description respectively 
                    gen.writeNumberField("code",value.code());
                    gen.writeStringField("description",value.description());
                    // Explicit end operation
                    gen.writeEndObject();
                }
            });

        // Register Module
        objectMapper.registerModule(module);

Then executing it again will get the result we expect. However, this is not reasonable.

4. Automatic global configuration in spring boot

In the Spring Boot application, we want to configure it globally. The automatic configuration of Spring Boot provides us with the possibility of customizing ObjectMapper. You only need to declare a Jackson 2objectmapperbuilder customizer and inject Spring IoC:

@Bean
public Jackson2ObjectMapperBuilderCustomizer enumCustomizer(){
    return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Enumerator.class, new JsonSerializer<Enumerator>() {
        @Override
        public void serialize(Enumerator value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    gen.writeStartObject();
                    gen.writeNumberField("code",value.code());
                    gen.writeStringField("description",value.description());
                    gen.writeEndObject();


        }
    });
}

This enables global configuration.

5. Summary

Here we show how to customize the Jackson library to achieve a more friendly serialization of enums. In fact, you can not only enumerate, but also customize other serialization, deserialization and time output formats. These features are left to you to explore. Pay more attention: Little Fatty brother of Minoan gets more development skills.

Pay attention to the official account: Felordcn for more information

Personal blog: https://felord.cn

Tags: Java Spring JSON

Posted on Mon, 22 Jun 2020 00:27:23 -0400 by suspect