目录
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
}
@Data
@Accessors(chain = true)
public class City {
private Distance distance;
}
枚举类序列化为Josn串
默认用法
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public enum Distance { ... }
City city = new City().setDistance(Distance.MILE);
String s = new ObjectMapper().writeValueAsString(city);
//执行结果
{"distance":"MILE"}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
import com.fasterxml.jackson.annotation.JsonFormat;
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Distance { ... }
City city = new City().setDistance(Distance.MILE);
String s = new ObjectMapper().writeValueAsString(city);
//执行结果
{"distance":{"unit":"miles","meters":1609.34}}
@JsonValue
@JsonValue
注解用于指定一个 JSON 属性的值
public enum Distance {
...
@JsonValue
public String getMeters() {
return meters;
}
}
City city = new City().setDistance(Distance.MILE);
String s = new ObjectMapper().writeValueAsString(city);
//执行结果
{"distance":1609.34}
自定义序列化 StdSerializer
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 { ... }
City city = new City().setDistance(Distance.MILE);
String s = new ObjectMapper().writeValueAsString(city);
//执行结果
{"distance":{"name":"MILE","unit":"miles","meters":1609.34}}
优先级高于@JsonSerialize(using = DistanceSerializer.class)
> @JsonValue
> @JsonFormat(shape = JsonFormat.Shape.OBJECT)
Josn串反序列化为枚举类
默认用法
public enum Distance { ... }
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
String json = "{\"distance\":\"KILOMETER\"}";
City city1 = new ObjectMapper().readValue(json, City.class);
System.out.println(city1.toString());
//执行结果
City(distance=KILOMETER)
忽略大小写
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
ObjectMapper 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)
@JsonValue
public enum Distance {
...
@JsonValue
public double getMeters() {
return meters;
}
}
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)
@JsonProperty
public enum Distance {
@JsonProperty("distance-in-km")
KILOMETER("km", 1000),
@JsonProperty("distance-in-miles")
MILE("miles", 1609.34);
...
}
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)
@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)
自定义反序列化
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