I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

This quick tutorial will show how to control the way Java Enums are serialized to JSON output with Jackson 2.

If you want to dig deeper and learn other cool things you can do with the Jackson 2 – head on over to the main Jackson tutorial.

Further reading:

Jackson – Custom Serializer

Control your JSON output with Jackson 2 by using a Custom Serializer.

Read more

XML Serialization and Deserialization with Jackson

This short tutorial shows how the Jackson library can be used to serialize Java object to XML and deserialize them back to objects.

Read more

Jackson – Decide What Fields Get Serialized/Deserialized

How to control which fields get serialized/deserialized by Jackson and which fields get ignored.

Read more

2. Controlling the Enum Representation

Let’s define the following Enum:

public enum Distance {
    KILOMETER("km", 1000), 
    MILE("miles", 1609.34),
    METER("meters", 1), 
    INCH("inches", 0.0254),
    CENTIMETER("cm", 0.01), 
    MILLIMETER("mm", 0.001);

    private String unit;
    private final double meters;

    private Distance(String unit, double meters) {
        this.unit = unit;
        this.meters = meters;
    }

    // standard getters and setters
}

3. Default Enum Representation

By default, Jackson will represent Java Enums as simple String – for example:

new ObjectMapper().writeValueAsString(Distance.MILE);

Will result in:

"MILE"

What we would like to get when marshaling this ENUM to a JSON Object is to give something like:

{"unit":"miles","meters":1609.34}

4. Enum as Json Object

Starting with Jackson 2.1.2 – the is now a configuration option that can handle this kind of representation – via the @JsonFormat annotation, at the Enum level:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Distance { ... }

This will lead to the correct result when serializing this enum for Distance.MILE:

{"unit":"miles","meters":1609.34}

5. Enums and @JsonValue

Yet another simple way of controlling the marshaling output for an enum is using the @JsonValue annotation on a getter:

public enum Distance { 
    ...
 
    @JsonValue
    public String getMeters() {
        return meters;
    }
}

What we’re saying here is that getMeters() is the actual representation of this enum. So the result of serializing:

1609.34

6. Custom Serializer for Enum

Before Jackson 2.1.2, or if even more customization is required for the enum – we can use a custom Jackson serializer – first we’ll need to define it:

public class DistanceSerializer extends StdSerializer {
    
    public DistanceSerializer() {
        super(Distance.class);
    }

    public DistanceSerializer(Class t) {
        super(t);
    }

    public void serialize(Distance distance, JsonGenerator generator,
      SerializerProvider provider) 
      throws IOException, JsonProcessingException {
        generator.writeStartObject();
        generator.writeFieldName("name");
        generator.writeString(distance.name());
        generator.writeFieldName("unit");
        generator.writeString(distance.getUnit());
        generator.writeFieldName("meters");
        generator.writeNumber(distance.getMeters());
        generator.writeEndObject();
    }
}

We will now tie together the serializer and the class it applies to:

@JsonSerialize(using = DistanceSerializer.class)
public enum TypeEnum { ... }

The result:

{"name":"MILE","unit":"miles","meters":1609.34}

7. Conclusion

This article illustrated how to gain better control over the serialization process and format of Java Enums.

The implementation of all these examples and code snippets can be found over on Github – this is an Eclipse based project, so it should be easy to import and run as it is.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS