枚举类使用Jackson进行序列化与反序列化(How To Serialize and Deserialize Enums with Jackson)

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
}

Serializing Enums to JSON

Default Enum Representation

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public enum Distance {
    
     ... }

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

结果
"MILE"

Enum as a JSON Object

import com.fasterxml.jackson.annotation.JsonFormat;

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

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

执行结果
{
    
    "unit":"miles","meters":1609.34}

Enums and @JsonValue

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Distance {
    
     
    ...
    @JsonValue
    public String getMeters() {
    
    
        return meters;
    }
}

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

执行结果
1609.34

发现:@JsonValue 优先级高于 @JsonFormat(shape = JsonFormat.Shape.OBJECT)

Custom Serializer for Enum

version of Jackson earlier than 2.1.2, or if even more customization is required for the enum, we can use a custom Jackson serializer.

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;

public class DistanceSerializer extends StdSerializer<Distance> {
    
    

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

    @Override
    public void serialize(Distance distance, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
    
    
        jsonGenerator.writeStartObject();
        jsonGenerator.writeFieldName("name");
        jsonGenerator.writeString(distance.name());
        jsonGenerator.writeFieldName("unit");
        jsonGenerator.writeString(distance.getUnit());
        jsonGenerator.writeFieldName("meters");
        jsonGenerator.writeNumber(distance.getMeters());
        jsonGenerator.writeEndObject();
    }
}
@JsonSerialize(using = DistanceSerializer.class)
public enum Distance {
    
     ... }

Deserializing JSON to Enum

Default Behavior

public enum Distance {
    
     ... }
@Data
public class City {
    
    
    private Distance distance;
}
 City city = new City().setDistance(Distance.KILOMETER);
 String s = new ObjectMapper().writeValueAsString(city);
 System.out.println(s); // {"distance":"KILOMETER"}
 
 String json = "{\"distance\":\"KILOMETER\"}";
 City city1 = new ObjectMapper().readValue(json, City.class);
 System.out.println(city1.toString()); // City(distance=KILOMETER)

do a case-insensitive deserialization

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
O
bjectMapper objectMapper = JsonMapper.builder()
        .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
        .build();
        
String json1 = "{\"distance\":\"KiLoMeTeR\"}";

City city2 = objectMapper.readValue(json1, City.class);
System.out.println(city2.toString()); // City(distance=KILOMETER)

Using @JsonValue

public enum Distance {
    
    
    ...
    @JsonValue
    public double getMeters() {
    
    
        return meters;
    }
}
@Data
public class City {
    
    
    private Distance distance;
}
import com.fasterxml.jackson.annotation.JsonValue;

String json3 = "{\"distance\":\"0.0254\"}";
City city3= new ObjectMapper().readValue(json3, City.class);
System.out.println(city3.toString()); // City(distance=INCH)

Using @JsonProperty

public enum Distance {
    
    
    @JsonProperty("distance-in-km")
    KILOMETER("km", 1000), 
    @JsonProperty("distance-in-miles")
    MILE("miles", 1609.34);
    ...
}
@Data
public class City {
    
    
    private Distance distance;
}
import com.fasterxml.jackson.annotation.JsonProperty;

String json = "{\"distance\":\"distance-in-km\"}";
City city1 = new ObjectMapper().readValue(json, City.class);
System.out.println(city1.toString()); // City(distance=KILOMETER)

Using @JsonCreator

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public enum Distance {
    
    

    @JsonCreator
    public static Distance forValues(@JsonProperty("unit") String unit, @JsonProperty("meters") double meters) {
    
    
        for (Distance distance : Distance.values()) {
    
    
            if (distance.unit.equals(unit) && Double.compare(distance.meters, meters) == 0) {
    
    
                return distance;
            }
        }
        return null;
    }

    ...
}
String json = "{\n" +
        "    \"distance\": {\n" +
        "        \"unit\":\"miles\", \n" +
        "        \"meters\":1609.34\n" +
        "    }\n" +
        "}";
        
String json1 = "{" + "\"distance\": {" + "\"unit\":\"miles\", " + "\"meters\":1609.34" + "}" + "}";

City city1 = new ObjectMapper().readValue(json, City.class);
System.out.println(city1.toString()); // City(distance=MILE)

City city2 = new ObjectMapper().readValue(json1, City.class);
System.out.println(city2.toString()); // City(distance=MILE)

Using a Custom Deserializer

public class CustomEnumDeserializer extends StdDeserializer<Distance> {
    
    

    @Override
    public Distance deserialize(JsonParser jsonParser, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    
    
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);

        String unit = node.get("unit").asText();
        double meters = node.get("meters").asDouble();

        for (Distance distance : Distance.values()) {
    
    
           
            if (distance.getUnit().equals(unit) && Double.compare(
              distance.getMeters(), meters) == 0) {
    
    
                return distance;
            }
        }

        return null;
    }
}
@JsonDeserialize(using = CustomEnumDeserializer.class)
public enum Distance {
    
    
   ...
}

-----------------------------------------------------------------------------读书笔记摘自 文章:How To Serialize and Deserialize Enums with Jackson

猜你喜欢

转载自blog.csdn.net/weixin_37646636/article/details/132059408