Jackson枚举类处理

MyBatis探究(五)——枚举类处理一文中,我们知道了如何在mybatis中使用枚举类型。这之后我们还需要正确处理与前端的交互,即正确处理枚举类型的序列化与反序列化操作。

本文将讨论如何在Jackson中处理枚举类型的序列化和反序列化。

默认情况下,Jackson会将Sex.MALE序列化成MALESex.FEMALE序列化成FEMALE;反序列化时Sex.MALE只能接受MALESex.FEMALE只能接受FEMALE。这不符合我们的需要,因此我们需要自定义序列化器和反序列化器。

序列化器

序列化器继承StdSerializer,重写serialize方法,向JsonGenerator中写入序列化后的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class BaseCodeEnumSerializer extends StdSerializer<BaseCodeEnum> {
public BaseCodeEnumSerializer() {
this(null);
}

public BaseCodeEnumSerializer(Class<BaseCodeEnum> t) {
super(t);
}

@Override
public void serialize(BaseCodeEnum value, JsonGenerator gen, SerializerProvider provider) throws IOException {
int code = value.getCode();
gen.writeNumber(code);
}
}

反序列化器

反序列化继承StdDeserializer,重写deserialize方法,根据JsonParser中的值返回反序列化后的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class BaseCodeEnumDeserializer<T extends BaseCodeEnum> extends StdDeserializer<T> {

private Class<T> type;

public BaseCodeEnumDeserializer() {
this(null);
}

public BaseCodeEnumDeserializer(Class<T> vc) {
super(vc);
type = vc;
}


@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
for (T t : type.getEnumConstants()) {
if (t.getCode() == Integer.valueOf(p.getText())) {
return t;
}
}
return null;
}
}

注册序列化器和反序列化器

1
2
3
4
5
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(BaseCodeEnum.class, new BaseCodeEnumSerializer());
module.addDeserializer(BaseCodeEnum.class, new BaseCodeEnumDeserializer<>());
mapper.registerModule(module);

新建SimpleModule,在SimpleModule中注册我们自定义的序列化和反序列化器,然后向ObjectMapper中注册module。

经过以上步骤,Jackson会将Sex.MALE序列化成1Sex.FEMALE序列化成0;反序列化时Sex.MALE接受1Sex.FEMALE接受0。结果符合我们的预期。