以下是我们一般的枚举类配合SpringMvc使用方式。
枚举类如下:
public enum Distance {KILOMETER("km", 1000),MILE("miles", 1609.34),METER("meters", 1);private String unit;private final double meters;Distance(String unit, double meters) {this.unit = unit;this.meters = meters;}
实体类如下:
public class City {private String id;private Distance distance;
Controller如下:
-- /api/v1?distance=KILOMETER
@GetMapping
public void get(Distance distance) -- /api/v1?distance=KILOMETER&id=1
@GetMapping
public void get(City city) -- json
{"id": "1","distance": "KILOMETER"
}
@PostMapping
public void post(@RequestBody City city)-- 反序列化
@GetMapping
public City get()
-- json
{"id": "1","distance": "KILOMETER"
}
默认所有的参数和响应都是大写的字符串枚举名称
我们想自定义序列化和反序列化字段,例如使用unit或者meters属性。
-- /api/v1?distance=KILOMETER
@GetMapping
public void get(Distance distance) -- /api/v1?distance=KILOMETER&id=1
@GetMapping
public void get(City city)
1. 定义IEnum接口
public interface IEnum {T getValue();
}
2.基于SpringMvc的Converter实现StringToEnum转换
public class StringToEnumConvertFactory implements ConditionalGenericConverter {@Overridepublic boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {return IEnum.class.isAssignableFrom(targetType.getObjectType()) && sourceType.getObjectType() == String.class;}@Overridepublic Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {IEnum[] enums = (IEnum[]) targetType.getObjectType().getEnumConstants();for (IEnum anEnum : enums) {if (Objects.equals(anEnum.getValue(), source)) {return anEnum;}}return null;}
}
3.把转换器注册到SpringMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(new StringToEnumConvertFactory());}
4.自定义枚举实现定义IEnum接口
public enum Distance implements IEnum {KILOMETER("km", 1000),MILE("miles", 1609.34),METER("meters", 1);private String unit;private final double meters;Distance(String unit, double meters) {this.unit = unit;this.meters = meters;}@Override // 这里选择转换的属性public String getValue() {return unit;}
}
实现效果如下:
-- /api/v1?distance=km
-- /api/v1?distance=miles
@GetMapping
public void get(Distance distance) -- /api/v1?distance=km&id=1
@GetMapping
public void get(City city)
-- json
{"id": "1","distance": "KILOMETER"
}
@PostMapping
public void post(@RequestBody City city)
直接在枚举的指定get方法使用@JsonValue
注解即可。
public enum Distance implements IEnum {KILOMETER("km", 1000),MILE("miles", 1609.34),METER("meters", 1);private String unit;private final double meters;Distance(String unit, double meters) {this.unit = unit;this.meters = meters;}@Override@JsonValue // 这里配置public String getValue() {return unit;}
}
实现效果如下:
-- json
{"id": "1","distance": "km"
}
@PostMapping
public void post(@RequestBody City city)
直接在get方法使用@JsonValue
注解即可。跟上面方式一样
实现效果如下:
-- 反序列化
@GetMapping
public City get()
-- json
{"id": "1","distance": "km"
}
更多Jackson序列化和反序列化参考:https://blog.csdn.net/hj_5346/article/details/127269700
- @JsonFormat(shape = JsonFormat.Shape.OBJECT)
- @JsonValue
- @JsonSerialize(using = DistanceSerializer.class)
- @JsonProperty(“distance-in-km”)
- @JsonCreator
- @JsonDeserialize(using = CustomEnumDeserializer.class)