我将杰克逊的enum
反序列化与代码中的名称不符,下面是json的示例。
{
"thing1": {"foo": "cool-guy"},
"thing2": {"foo": "loser-face"}
}
以下是enum
,我稍后会解释interface
。
enum Foo implements HasText {
COOL_GUY("cool-guy"), LOSER_FACE("loser-face"), // etc...
private String text;
private Foo(String text) {
this.text = text;
}
@Override
public String getText() {
return text;
}
}
我知道如何通过在foo的setter方法上创建反序列化器(下面)和注释enum
来为每个@JsonDeserialize(using = FooDeserializer .class)
单独解决此问题。
public class FooDeserializer extends JsonDeserializer<Enum<Foo>> {
@Override
public Foo deserialize(JsonParser p, DeserializationContext context) throws Exception {
if (p.getCurrentToken().equals(JsonToken.VALUE_STRING)) {
String jsonText = p.getText();
Stream<Foo> stream = Arrays.asList(Foo.values()).stream();
return stream.filter(a -> a.getText().equals(jsonText.toLowerCase())).findAny().get();
}
throw context.mappingException(Foo.class);
}
}
有没有办法抽象地这样做?这就是为什么我将HasText interface
添加到我的所有枚举中,希望有办法做这样的事情:
public class EnumWithTextDeserializer<T extends Enum<T> & HasText> extends JsonDeserializer<T> {
@Override
public T deserialize(JsonParser p, DeserializationContext context) throws Exception {
if (p.getCurrentToken().equals(JsonToken.VALUE_STRING)) {
final String jsonText = p.getText();
final Stream<T> stream = Arrays.asList(runtimeClass().getEnumConstants()).stream();
return stream.filter(a -> a.getText().equals(jsonText.toLowerCase())).findAny().get();
}
throw context.mappingException(runtimeClass());
}
@SuppressWarnings("unchecked")
private Class<T> runtimeClass() {
ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
return (Class<T>) superclass.getActualTypeArguments()[0];
}
}
编译不会让我用这个类注释setter方法(@JsonDeserialize(using = EnumWithTextDeserializer.class)
),因为
Type mismatch: cannot convert from Class<EnumWithTextDeserializer> to Class<? extends JsonDeserializer<?>>".
真的,我希望能够做的就是根据getText()方法对这些enum
进行反序列化。
答案 0 :(得分:1)
为了反序列化,您可以使用@JsonValue
指定字符串值。
public enum FooEnum implements WithText {
AWESOME("awesome-rad"),
NARLY("totally-narly");
private final String text;
FooEnum(String text) {
this.text = text;
}
@Override
@JsonValue
public String getText() {
return text;
}
}
然后执行此代码以序列化/反序列化
ImmutableMap<String, FooEnum> map = ImmutableMap.of("value", FooEnum.AWESOME, "value2", FooEnum.NARLY);
final String value;
try {
value = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
throw Throwables.propagate(e);
}
Map<String, FooEnum> read;
try {
read = objectMapper.readValue(value, new TypeReference<Map<String, FooEnum>>() {});
} catch (IOException e) {
throw Throwables.propagate(e);
}
我明白了:
read = {LinkedHashMap@4627} size = 2
0 = {LinkedHashMap$Entry@4631} "value1" -> "AWESEOME"
1 = {LinkedHashMap$Entry@4632} "value2" -> "NARLY"