public enum ClusterType {
TEMPERATURE("0402"),
HUMIDITY("0405"),
ENERGY_DETAILS("0702"),
SMART_SOCKET_STATUS("0006"),
ALARMED("0500");
private String value = null;
ClusterType(String byteStr) {
this.value = byteStr;
}
@JsonCreator
public static ClusterType fromValue(final String val){
return (ClusterType) CollectionUtils.find(Arrays.asList(ClusterType.values()), new Predicate() {
public boolean evaluate(Object object) {
ClusterType candidate = (ClusterType) object;
return StringUtils.equals(candidate.value, val);
}
});
}
@JsonValue
public String getValue(){
return value;
}
public byte[] get() {
return ByteUtils.hexStringToByteArray(value);
}
public boolean equals(String cluster) {
return StringUtils.equals(cluster, value);
}
}
我有
的上述枚举@JsonValue public String getValue(){ 回报值; }
部分和样本测试类如...
公共课Foo {
public static void main(String[] args) { try { ObjectMapper objectMapper = new ObjectMapper(); ClusterType []arrayRep = new ClusterType[]{ClusterType.ALARMED, ClusterType.TEMPERATURE}; Map<String, ClusterType> mapRepAsValue = new HashMap<>(); mapRepAsValue.put("1", ClusterType.ALARMED); mapRepAsValue.put("2", ClusterType.TEMPERATURE); Map<ClusterType, String> mapRepAsKey = new HashMap<>(); mapRepAsKey.put(ClusterType.ALARMED, "1"); mapRepAsKey.put(ClusterType.TEMPERATURE, "2"); System.out.println(objectMapper.writeValueAsString(arrayRep)); System.out.println(objectMapper.writeValueAsString(mapRepAsValue)); System.out.println(objectMapper.writeValueAsString(mapRepAsKey)); } catch (JsonProcessingException e) { e.printStackTrace(); } } }
此测试类打印出
["0500","0402"]
{"2":"0402","1":"0500"}
{"TEMPERATURE":"2","ALARMED":"1"}
@JsonValue在枚举字段上使用时,它是地图的键。
在序列化地图时,有没有办法将此枚举用作键?
感谢。
答案 0 :(得分:3)
杰克逊使用MapSerializer
序列化Map
类型,并使用StdKeySerializer
来序列化密钥。它实现为
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (value instanceof Date) {
provider.defaultSerializeDateKey((Date) value, jgen);
} else {
jgen.writeFieldName(value.toString());
}
}
您可以看到只获取对象的toString()
值。因此,您可以覆盖toString()
中的enum
方法
public String toString() {
return getValue();
}
@JsonValue
变得毫无用处。
或者,如果您需要toString()
保持不变(或默认),则可以创建包装Map
class CustomType {
private Map<ClusterType, String> map;
@JsonAnyGetter // necessary to unwrap the Map to the root object, see here: http://jira.codehaus.org/browse/JACKSON-765
@JsonSerialize(keyUsing = ClusterTypeKeySerializer.class)
public Map<ClusterType, String> getMap() {
return map;
}
public void setMap(Map<ClusterType, String> map) {
this.map = map;
}
}
并使用自定义JsonSerializer
class ClusterTypeKeySerializer extends StdSerializer<ClusterType> {
protected ClusterTypeKeySerializer() {
super(ClusterType.class);
}
@Override
public void serialize(ClusterType value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonGenerationException {
jgen.writeFieldName(value.getValue());
}
}
使用ClusterType#getValue()
方法。同样,我们不使用@JsonValue
。
答案 1 :(得分:3)
实际上,我认为这只是一个尚未添加的功能,按照:
https://github.com/FasterXML/jackson-databind/issues/47
所以尽管@JsonValue
在反序列化方面对Enums工作正常,但它还不适用于序列化。如果有人有时间解决这个问题,那么项目总是愿意做出贡献 - 这不应该是一件大事。