diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java index afb4e0e18d..bcccd9eaa0 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java @@ -244,7 +244,7 @@ public JsonSerializer createKeySerializer(SerializerProvider ctxt, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } // null -> no TypeSerializer for key-serializer use case - ser = new JsonValueSerializer(acc, null, delegate); + ser = JsonValueSerializer.construct(config, acc, null, delegate); } else { ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass(), beanDesc.getClassInfo()); @@ -405,7 +405,8 @@ protected final JsonSerializer findSerializerByAnnotations(SerializerProvider if (typeSerializer == null) { typeSerializer = createTypeSerializer(prov.getConfig(), valueType); } - return new JsonValueSerializer(valueAccessor, typeSerializer, valueSerializer); + return JsonValueSerializer.construct(prov.getConfig(), valueAccessor, + typeSerializer, valueSerializer); } // No well-known annotations... return null; diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java index 3c3ac0da59..45469063b7 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; +import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; @@ -73,6 +74,14 @@ public class JsonValueSerializer */ protected final boolean _forceTypeInformation; + /** + * Names of properties to ignore from Value class accessed using + * accessor. + * + * @since 2.16 + */ + protected final Set _ignoredProperties; + /** * If value type cannot be statically determined, mapping from * runtime value types to serializers are cached in this object. @@ -97,7 +106,8 @@ public class JsonValueSerializer */ @SuppressWarnings("unchecked") public JsonValueSerializer(AnnotatedMember accessor, - TypeSerializer vts, JsonSerializer ser) + TypeSerializer vts, JsonSerializer ser, + Set ignoredProperties) { super(accessor.getType()); _accessor = accessor; @@ -106,15 +116,23 @@ public JsonValueSerializer(AnnotatedMember accessor, _valueSerializer = (JsonSerializer) ser; _property = null; _forceTypeInformation = true; // gets reconsidered when we are contextualized + _ignoredProperties = ignoredProperties; _dynamicSerializers = PropertySerializerMap.emptyForProperties(); } + @Deprecated // since 2.16 + public JsonValueSerializer(AnnotatedMember accessor, + TypeSerializer vts, JsonSerializer ser) + { + this(accessor, vts, ser, Collections.emptySet()); + } + /** * @deprecated Since 2.12 */ @Deprecated public JsonValueSerializer(AnnotatedMember accessor, JsonSerializer ser) { - this(accessor, null, ser); + this(accessor, null, ser, Collections.emptySet()); } // @since 2.12 @@ -129,9 +147,24 @@ public JsonValueSerializer(JsonValueSerializer src, BeanProperty property, _valueSerializer = (JsonSerializer) ser; _property = property; _forceTypeInformation = forceTypeInfo; + _ignoredProperties = src._ignoredProperties; _dynamicSerializers = PropertySerializerMap.emptyForProperties(); } + /** + * @since 2.16 + */ + public static JsonValueSerializer construct(SerializationConfig config, + AnnotatedMember accessor, + TypeSerializer vts, JsonSerializer ser) + { + JsonIgnoreProperties.Value ignorals = config.getAnnotationIntrospector() + .findPropertyIgnoralByName(config, accessor); + final Set ignoredProperties = ignorals.findIgnoredForSerialization(); + ser = _withIgnoreProperties(ser, ignoredProperties); + return new JsonValueSerializer(accessor, vts, ser, ignoredProperties); + } + @SuppressWarnings("unchecked") private final static Class _notNullClass(Class cls) { return (cls == null) ? Object.class : (Class) cls; @@ -205,6 +238,8 @@ public JsonSerializer createContextual(SerializerProvider ctxt, */ // 05-Sep-2013, tatu: I _think_ this can be considered a primary property... ser = ctxt.findPrimaryPropertySerializer(_valueType, property); + ser = _withIgnoreProperties(ser, _ignoredProperties); + /* 09-Dec-2010, tatu: Turns out we must add special handling for * cases where "native" (aka "natural") type is being serialized, * using standard serializer @@ -416,12 +451,13 @@ protected JsonSerializer _findDynamicSerializer(SerializerProvider ctxt, if (_valueType.hasGenericTypes()) { final JavaType fullType = ctxt.constructSpecializedType(_valueType, valueClass); serializer = ctxt.findPrimaryPropertySerializer(fullType, _property); + serializer = _withIgnoreProperties(serializer, _ignoredProperties); PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.addSerializer(fullType, serializer); _dynamicSerializers = result.map; } else { serializer = ctxt.findPrimaryPropertySerializer(valueClass, _property); // [databind#3647] : Support `@JsonIgnoreProperties` to work with `@JsonValue` - serializer = (JsonSerializer) _withIgnoreProperties(ctxt, serializer); + serializer = _withIgnoreProperties(serializer, _ignoredProperties); PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.addSerializer(valueClass, serializer); _dynamicSerializers = result.map; } @@ -451,18 +487,17 @@ protected JsonSerializer _findDynamicSerializer(SerializerProvider ctxt, /** * Internal helper that configures the provided {@code ser} to ignore properties specified by {@link JsonIgnoreProperties}. * - * @param ctxt For introspection. * @param ser Serializer to be configured * @return Configured serializer with specified properties ignored * @since 2.16 */ @SuppressWarnings("unchecked") - protected JsonSerializer _withIgnoreProperties(SerializerProvider ctxt, JsonSerializer ser) { - JsonIgnoreProperties.Value ignorals = ctxt.getAnnotationIntrospector() - .findPropertyIgnoralByName(ctxt.getConfig(), _accessor); - Set ignored = ignorals.findIgnoredForSerialization(); - if (!ignored.isEmpty()) { - ser = ser.withIgnoredProperties(ignored); + protected static JsonSerializer _withIgnoreProperties(JsonSerializer ser, + Set ignoredProperties) { + if (ser != null) { + if (!ignoredProperties.isEmpty()) { + ser = ser.withIgnoredProperties(ignoredProperties); + } } return (JsonSerializer) ser; } diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonValueIgnore3647Test.java b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonValueIgnore3647Test.java index e401ce09cf..7903ce6929 100644 --- a/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonValueIgnore3647Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/ser/filter/JsonValueIgnore3647Test.java @@ -8,7 +8,7 @@ // [databind#3647] : Support @JsonIgnoreProperties to work with @JsonValue public class JsonValueIgnore3647Test extends BaseMapTest { - static class Foo3647 { + final static class Foo3647 { public String p1 = "hello"; public String p2 = "world"; }