From 45bee0d4ab5323a0ec403185607f5c0a5884dbb8 Mon Sep 17 00:00:00 2001 From: Joe Littlejohn Date: Sun, 4 Jun 2017 15:04:28 +0100 Subject: [PATCH] Support READ_UNKNOWN_ENUM_VALUES_AS_NULL with @JsonCreator The deserialization feature READ_UNKNOWN_ENUM_VALUES_AS_NULL allows enum values that are not recognised to take a null value when parsed. Before this commit, this deserialization feature did not work whenever an enum had a method marked @JsonCreator, and the enum creator method itself had to choose null in the case of unknown input. With this change, if an enum creator method throws an IllegalArgumentException then this is considered to be an unknown value and (if READ_UNKNOWN_ENUM_VALUES_AS_NULL is active) then null will be used. --- .../std/FactoryBasedEnumDeserializer.java | 6 ++++++ .../deser/jdk/EnumDeserializationTest.java | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java index 522855f6d7..0c6d43a08d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java @@ -134,6 +134,12 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx return _factory.callOnWith(_valueClass, value); } catch (Exception e) { Throwable t = ClassUtil.throwRootCauseIfIOE(e); + + if (ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL) && + t instanceof IllegalArgumentException) { + return null; + } + return ctxt.handleInstantiationProblem(_valueClass, value, t); } } diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java index 2a0bc19af9..07c74b32fb 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java @@ -116,6 +116,17 @@ static enum EnumWithDefaultAnnoAndConstructor { } } + static enum StrictEnumCreator { + A, B; + + @JsonCreator public static StrictEnumCreator fromId(String value) { + for (StrictEnumCreator e: values()) { + if (e.name().toLowerCase().equals(value)) return e; + } + throw new IllegalArgumentException(value); + } + } + // // public enum AnEnum { @@ -321,6 +332,16 @@ public void testAllowUnknownEnumValuesReadAsNull() throws Exception assertNull(reader.forType(TestEnum.class).readValue(" 4343 ")); } + // Ability to ignore unknown Enum values: + + public void testAllowUnknownEnumValuesReadAsNullWithCreatorMethod() throws Exception + { + // can not use shared mapper when changing configs... + ObjectReader reader = MAPPER.reader(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL); + assertNull(reader.forType(StrictEnumCreator.class).readValue("\"NO-SUCH-VALUE\"")); + assertNull(reader.forType(StrictEnumCreator.class).readValue(" 4343 ")); + } + public void testAllowUnknownEnumValuesForEnumSets() throws Exception { ObjectReader reader = MAPPER.reader(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL);