Skip to content

Commit 09c4b39

Browse files
committed
Improvements to handling/validation of JsonCreator with Enum types
1 parent b283aad commit 09c4b39

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,10 +1482,13 @@ public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
14821482
}
14831483
Class<?> returnType = factory.getRawReturnType();
14841484
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
1485-
if (returnType.isAssignableFrom(enumClass)) {
1486-
deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory, valueInstantiator, creatorProps);
1487-
break;
1485+
if (!returnType.isAssignableFrom(enumClass)) {
1486+
ctxt.reportBadDefinition(type, String.format(
1487+
"Invalid `@JsonCreator` annotated Enum factory method [%s]: needs to return compatible type",
1488+
factory.toString()));
14881489
}
1490+
deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory, valueInstantiator, creatorProps);
1491+
break;
14891492
}
14901493
}
14911494

@@ -2219,7 +2222,7 @@ protected boolean _hasCreatorAnnotation(DeserializationContext ctxt,
22192222
}
22202223
return false;
22212224
}
2222-
2225+
22232226
/*
22242227
/**********************************************************
22252228
/* Deprecated helper methods

src/main/java/com/fasterxml/jackson/databind/deser/std/EnumDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
168168
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
169169
{
170170
JsonToken curr = p.currentToken();
171-
171+
172172
// Usually should just get string value:
173173
if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
174174
CompactStringObjectMap lookup = ctxt.isEnabled(DeserializationFeature.READ_ENUMS_USING_TO_STRING)

src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,37 @@ public Boolean supportsUpdate(DeserializationConfig config) {
106106
@Override
107107
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
108108
{
109-
Object value = null;
109+
System.err.println("FactoryBasedEnumDeserializer.deserialize... deser == "+_deser);
110+
111+
Object value;
110112
if (_deser != null) {
111113
value = _deser.deserialize(p, ctxt);
112114
} else if (_hasArgs) {
113115
JsonToken curr = p.currentToken();
114-
//There can be a JSON object passed for deserializing an Enum,
115-
//the below case handles it.
116-
if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
117-
value = p.getText();
118-
} else if ((_creatorProps != null) && p.isExpectedStartObjectToken()) {
116+
117+
// 30-Mar-2020, tatu: For properties-based one, MUST get JSON Object (before
118+
// 2.11, was just assuming match)
119+
if (_creatorProps != null) {
120+
if (!p.isExpectedStartObjectToken()) {
121+
final JavaType targetType = getValueType(ctxt);
122+
ctxt.reportInputMismatch(targetType,
123+
"Input mismatch reading Enum %s: properties-based `@JsonCreator` (%s) expects JSON Object (JsonToken.START_OBJECT), got JsonToken.%s",
124+
ClassUtil.getTypeDescription(targetType), _factory, p.currentToken());
125+
}
119126
if (_propCreator == null) {
120127
_propCreator = PropertyBasedCreator.construct(ctxt, _valueInstantiator, _creatorProps,
121128
ctxt.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES));
122129
}
123130
p.nextToken();
124131
return deserializeEnumUsingPropertyBased(p, ctxt, _propCreator);
132+
}
133+
134+
//There can be a JSON object passed for deserializing an Enum,
135+
//the below case handles it.
136+
if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
137+
value = p.getText();
138+
} else if (curr == JsonToken.VALUE_NUMBER_INT) {
139+
value = p.getNumberValue();
125140
} else {
126141
value = p.getValueAsString();
127142
}

0 commit comments

Comments
 (0)