diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-06-19 19:19:48 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-06-19 19:19:48 -0700 |
commit | 65c81af00cdfc9af51f89d249061acca6f9b68b5 (patch) | |
tree | 046ae9acbd774dfab3ee9535588e990f38fe6c44 /src | |
parent | 75c992461bf5f332984c9c52ae8b649ae1f33557 (diff) | |
parent | 5d1f645b6d8fa6b15800c54272764b715636f95b (diff) | |
download | jackson-databind-65c81af00cdfc9af51f89d249061acca6f9b68b5.tar.gz |
Merge branch '2.11' into 2.12
Diffstat (limited to 'src')
4 files changed, 109 insertions, 18 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java index 338468d7f..d16de4a7e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java +++ b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java @@ -344,8 +344,6 @@ public class ObjectMapper } } - - /* /********************************************************** /* Internal constants, singletons @@ -1851,7 +1849,7 @@ public class ObjectMapper /** * Convenience method that is equivalent to calling *<pre> - * enableDefaultTyping(ptv, DefaultTyping.OBJECT_AND_NON_CONCRETE); + * activateDefaultTyping(ptv, DefaultTyping.OBJECT_AND_NON_CONCRETE); *</pre> *<p> * NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security @@ -1869,7 +1867,7 @@ public class ObjectMapper /** * Convenience method that is equivalent to calling *<pre> - * enableDefaultTyping(ptv, dti, JsonTypeInfo.As.WRAPPER_ARRAY); + * activateDefaultTyping(ptv, dti, JsonTypeInfo.As.WRAPPER_ARRAY); *</pre> *<p> * NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security @@ -1888,11 +1886,11 @@ public class ObjectMapper } /** - * Method for enabling automatic inclusion of type information, needed - * for proper deserialization of polymorphic types (unless types + * Method for enabling automatic inclusion of type information ("Default Typing"), + * needed for proper deserialization of polymorphic types (unless types * have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}). *<P> - * NOTE: use of <code>JsonTypeInfo.As#EXTERNAL_PROPERTY</code> <b>NOT SUPPORTED</b>; + * NOTE: use of {@code JsonTypeInfo.As#EXTERNAL_PROPERTY} <b>NOT SUPPORTED</b>; * and attempts of do so will throw an {@link IllegalArgumentException} to make * this limitation explicit. *<p> @@ -1924,8 +1922,8 @@ public class ObjectMapper } /** - * Method for enabling automatic inclusion of type information -- needed - * for proper deserialization of polymorphic types (unless types + * Method for enabling automatic inclusion of type information ("Default Typing") + * -- needed for proper deserialization of polymorphic types (unless types * have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) -- * using "As.PROPERTY" inclusion mechanism and specified property name * to use for inclusion (default being "@class" since default type information @@ -1968,8 +1966,8 @@ public class ObjectMapper } /** - * Method for enabling automatic inclusion of type information, using - * specified handler object for determining which types this affects, + * Method for enabling automatic inclusion of type information ("Default Typing"), + * using specified handler object for determining which types this affects, * as well as details of how information is embedded. *<p> * NOTE: use of Default Typing can be a potential security risk if incoming diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java index 5f30bc2fc..acba22f92 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java @@ -84,7 +84,10 @@ public class StdTypeResolverBuilder // 03-Oct-2016, tatu: As per [databind#1395] better prevent use for primitives, // regardless of setting if (baseType.isPrimitive()) { - return null; + // 19-Jun-2020, tatu: But for [databind#2753], allow overriding + if (!allowPrimitiveTypes(config, baseType)) { + return null; + } } TypeIdResolver idRes = idResolver(config, baseType, subTypeValidator(config), subtypes, true, false); @@ -118,7 +121,10 @@ public class StdTypeResolverBuilder // 03-Oct-2016, tatu: As per [databind#1395] better prevent use for primitives, // regardless of setting if (baseType.isPrimitive()) { - return null; + // 19-Jun-2020, tatu: But for [databind#2753], allow overriding + if (!allowPrimitiveTypes(config, baseType)) { + return null; + } } // 27-Apr-2019, tatu: Part of [databind#2195]; must first check whether any subtypes @@ -151,7 +157,6 @@ public class StdTypeResolverBuilder protected JavaType defineDefaultImpl(DeserializationConfig config, JavaType baseType) { JavaType defaultImpl; if (_defaultImpl == null) { - //Fis of issue #955 if (config.isEnabled(MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL) && !baseType.isAbstract()) { defaultImpl = baseType; } else { @@ -332,4 +337,31 @@ public class StdTypeResolverBuilder ClassUtil.classNameOf(ptv), ClassUtil.classNameOf(baseType.getRawClass())) ); } + + /* + /********************************************************** + /* Overridable helper methods + /********************************************************** + */ + + /** + * Overridable helper method that is called to determine whether type serializers + * and type deserializers may be created even if base type is Java {@code primitive} + * type. + * Default implementation simply returns {@code false} (since primitive types can not + * be sub-classed, are never polymorphic) but custom implementations + * may change the logic for some special cases. + * + * @param config Currently active configuration + * @param baseType Primitive base type for property being handled + * + * @return True if type (de)serializer may be created even if base type is Java + * {@code primitive} type; false if not + * + * @since 2.11.1 + */ + protected boolean allowPrimitiveTypes(MapperConfig<?> config, + JavaType baseType) { + return false; + } } diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java index 5090580e2..95621c9a5 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java @@ -332,7 +332,7 @@ public abstract class BeanSerializerBase } } } - + if (prop.hasSerializer()) { continue; } @@ -354,9 +354,8 @@ public abstract class BeanSerializerBase } } ser = provider.findValueSerializer(type, prop); - /* 04-Feb-2010, tatu: We may have stashed type serializer for content types - * too, earlier; if so, it's time to connect the dots here: - */ + // 04-Feb-2010, tatu: We may have stashed type serializer for content types + // too, earlier; if so, it's time to connect the dots here: if (type.isContainerType()) { TypeSerializer typeSer = type.getContentType().getTypeHandler(); if (typeSer != null) { diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/deftyping/DefaultTypeResolverForLong2753Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/deftyping/DefaultTypeResolverForLong2753Test.java new file mode 100644 index 000000000..b9ff71d00 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/deftyping/DefaultTypeResolverForLong2753Test.java @@ -0,0 +1,62 @@ +package com.fasterxml.jackson.databind.jsontype.deftyping; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.*; + +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.annotation.JsonTypeResolver; +import com.fasterxml.jackson.databind.cfg.MapperConfig; +import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; + +public class DefaultTypeResolverForLong2753Test extends BaseMapTest +{ + static class Data { + private Long key; + + @JsonCreator + private Data(@JsonProperty("key") Long key) { + this.key = key; + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") + @JsonTypeResolver(MyTypeResolverBuilder.class) + public long key() { + return key; + } + } + + static class MyTypeResolverBuilder extends StdTypeResolverBuilder { + @Override + protected boolean allowPrimitiveTypes(MapperConfig<?> config, + JavaType baseType) { + return true; + } + } + + public void testDefaultTypingWithLong() throws Exception + { + Data data = new Data(1L); + Map<String, Object> mapData = new HashMap<>(); + mapData.put("longInMap", 2L); + mapData.put("longAsField", data); + + // Configure Jackson to preserve types +// StdTypeResolverBuilder resolver = new MyTypeResolverBuilder(); +// resolver.init(JsonTypeInfo.Id.CLASS, null); +// resolver.inclusion(JsonTypeInfo.As.PROPERTY); +// resolver.typeProperty("__t"); + ObjectMapper mapper = jsonMapperBuilder() +// .setDefaultTyping(resolver) + .enable(SerializationFeature.INDENT_OUTPUT) + .build(); + + // Serialize + String json = mapper.writeValueAsString(mapData); +//System.err.println("JSON:\n"+json); + Map<?,?> result = mapper.readValue(json, Map.class); + assertNotNull(result); + assertEquals(2, result.size()); + } +} |