New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deserializing enum error by using int/Integer value with @JsonValue #2754
Comments
I found the code that caused this situation int the com.fasterxml.jackson.databind.deser.std.EnumDeserializer#deserialize(JsonParser p, DeserializationContext ctxt) it will deserialized the enum using index directly if public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
JsonToken curr = p.currentToken();
// Usually should just get string value:
if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
CompactStringObjectMap lookup = ctxt.isEnabled(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
? _getToStringLookup(ctxt) : _lookupByName;
final String name = p.getText();
Object result = lookup.find(name);
if (result == null) {
return _deserializeAltString(p, ctxt, lookup, name);
}
return result;
}
// But let's consider int acceptable as well (if within ordinal range)
if (curr == JsonToken.VALUE_NUMBER_INT) {
// ... unless told not to do that
int index = p.getIntValue();
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) {
return ctxt.handleWeirdNumberValue(_enumClass(), index,
"not allowed to deserialize Enum value out of number: disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow"
);
}
if (index >= 0 && index < _enumsByIndex.length) {
return _enumsByIndex[index];
}
if ((_enumDefaultValue != null)
&& ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE)) {
return _enumDefaultValue;
}
if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
return ctxt.handleWeirdNumberValue(_enumClass(), index,
"index value outside legal index range [0..%s]",
_enumsByIndex.length-1);
}
return null;
}
return _deserializeOther(p, ctxt);
} It might be a bug? When the int/Integer parameter is annotated by @JsonValue , whether consider using annotations instead of index? |
I think this is because currently For now, workaround would be to create static factory method annotated with @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
static ColorEnum find(int value) {
// find matching isntance
} which is more work but actually works. We can keep this issue open as request for enhancement. |
This really works using static factory method with But threre are a lot of enum like this in my project. The factory method is static mean can‘t be inherit so that i have to write manually for every enum. Thanks very much if can solve this problem in the next version |
@zzzzbw I agree, factory method is more work. It should be possible to add helper methods for building But I do hope we can support this in future as this is perfectly sensible usage pattern. |
Realized that this is a duplicate of #1850 so closing in favor of that one. |
When annotating @JsonValue on the int/Integer value, the enum can be serialized as number successfully. when i deserializing it by using a number JSON string, it will throw exception.
But it work well when using a 'String' type JSON string.
Whether the type of serialized values and deserialized parameters should be consistent?
follow is some sample code:
the result is:
ps: the version is 2.11.0
The text was updated successfully, but these errors were encountered: