diff options
author | Cowtowncoder <tatu.saloranta@iki.fi> | 2015-04-02 14:32:26 -0700 |
---|---|---|
committer | Cowtowncoder <tatu.saloranta@iki.fi> | 2015-04-02 14:32:26 -0700 |
commit | 119ddc9701c94ac184362166742ceaa7437eec8f (patch) | |
tree | 7e97514c2098cec5c3b80aa826f57605071c074c /src/main | |
parent | fa1c2ff7eefd68061ae0cc3f630e87d16d1b2bb5 (diff) | |
download | jackson-databind-119ddc9701c94ac184362166742ceaa7437eec8f.tar.gz |
Fix #731
Diffstat (limited to 'src/main')
5 files changed, 66 insertions, 12 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/JavaType.java b/src/main/java/com/fasterxml/jackson/databind/JavaType.java index 822130b00..07b6ba968 100644 --- a/src/main/java/com/fasterxml/jackson/databind/JavaType.java +++ b/src/main/java/com/fasterxml/jackson/databind/JavaType.java @@ -291,6 +291,17 @@ public abstract class JavaType public boolean isMapLikeType() { return false; } /** + * Convenience method, short-hand for + *<code> + * getRawClass() == Object.class + *</code> + * and used to figure if we basically have "untyped" type object. + * + * @since 2.5 + */ + public final boolean isJavaLangObject() { return _class == Object.class; } + + /** * Accessor for checking whether handlers for dealing with values of * this type should use static typing (as opposed to dynamic typing). * Note that while value of 'true' does mean that static typing is to @@ -299,7 +310,7 @@ public abstract class JavaType * @since 2.2 */ public final boolean useStaticType() { return _asStatic; } - + /* /********************************************************** /* Public API, type parameter access; pass-through diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java index ec540cc6d..14e6d9345 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java @@ -159,7 +159,8 @@ public class BeanSerializerFactory // [#359]: explicitly check (again) for @JsonSerializer... ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo()); } - if (ser == null) { + // [databind#731]: Should skip if nominally java.lang.Object + if (ser == null && !delegateType.isJavaLangObject()) { ser = _createSerializer2(prov, delegateType, beanDesc, true); } return new StdDelegatingSerializer(conv, delegateType, ser); 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 ee8735c2f..3e1164808 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 @@ -366,7 +366,9 @@ public abstract class BeanSerializerBase if (convDef != null) { Converter<Object,Object> conv = provider.converterInstance(prop.getMember(), convDef); JavaType delegateType = conv.getOutputType(provider.getTypeFactory()); - JsonSerializer<?> ser = provider.findValueSerializer(delegateType, prop); + // [databind#731]: Should skip if nominally java.lang.Object + JsonSerializer<?> ser = delegateType.isJavaLangObject() ? null + : provider.findValueSerializer(delegateType, prop); return new StdDelegatingSerializer(conv, delegateType, ser); } } diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdDelegatingSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdDelegatingSerializer.java index 0b435ead1..6c52b736e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdDelegatingSerializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdDelegatingSerializer.java @@ -115,13 +115,20 @@ public class StdDelegatingSerializer if (delegateType == null) { delegateType = _converter.getOutputType(provider.getTypeFactory()); } - delSer = provider.findValueSerializer(delegateType); + /* 02-Apr-2015, tatu: For "dynamic case", where type is only specified as + * java.lang.Object (or missing generic), [databind#731] + */ + if (!delegateType.isJavaLangObject()) { + delSer = provider.findValueSerializer(delegateType); + } } if (delSer instanceof ContextualSerializer) { delSer = provider.handleSecondaryContextualization(delSer, property); } - return (delSer == _delegateSerializer) ? this - : withDelegate(_converter, delegateType, delSer); + if (delSer == _delegateSerializer && delegateType == _delegateType) { + return this; + } + return withDelegate(_converter, delegateType, delSer); } /* @@ -154,7 +161,12 @@ public class StdDelegatingSerializer provider.defaultSerializeNull(gen); return; } - _delegateSerializer.serialize(delegateValue, gen, provider); + // 02-Apr-2015, tatu: As per [databind#731] may need to do dynamic lookup + JsonSerializer<Object> ser = _delegateSerializer; + if (ser == null) { + ser = _findSerializer(delegateValue, provider); + } + ser.serialize(delegateValue, gen, provider); } @Override @@ -165,14 +177,21 @@ public class StdDelegatingSerializer * let's give it a chance? */ Object delegateValue = convertValue(value); - _delegateSerializer.serializeWithType(delegateValue, gen, provider, typeSer); + JsonSerializer<Object> ser = _delegateSerializer; + if (ser == null) { + ser = _findSerializer(value, provider); + } + ser.serializeWithType(delegateValue, gen, provider, typeSer); } @Override - @Deprecated // since 1.5 + @Deprecated // since 2.5 public boolean isEmpty(Object value) { Object delegateValue = convertValue(value); + if (_delegateSerializer == null) { // best we can do for now, too costly to look up + return (value == null); + } return _delegateSerializer.isEmpty(delegateValue); } @@ -180,6 +199,9 @@ public class StdDelegatingSerializer public boolean isEmpty(SerializerProvider prov, Object value) { Object delegateValue = convertValue(value); + if (_delegateSerializer == null) { // best we can do for now, too costly to look up + return (value == null); + } return _delegateSerializer.isEmpty(prov, delegateValue); } @@ -216,7 +238,10 @@ public class StdDelegatingSerializer /* 03-Sep-2012, tatu: Not sure if this can be made to really work * properly... but for now, try this: */ - _delegateSerializer.acceptJsonFormatVisitor(visitor, typeHint); + // 02-Apr-2015, tatu: For dynamic case, very little we can do + if (_delegateSerializer != null) { + _delegateSerializer.acceptJsonFormatVisitor(visitor, typeHint); + } } /* @@ -239,4 +264,19 @@ public class StdDelegatingSerializer protected Object convertValue(Object value) { return _converter.convert(value); } + + /** + * Helper method used for locating serializer to use in dynamic use case, where + * actual type value gets converted to is not specified beyond basic + * {@link java.lang.Object}, and where serializer needs to be located dynamically + * based on actual value type. + * + * @since 2.6 + */ + protected JsonSerializer<Object> _findSerializer(Object value, SerializerProvider serializers) + throws JsonMappingException + { + // NOTE: will NOT call contextualization + return serializers.findValueSerializer(value.getClass()); + } } diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java index 31bbe0870..6089e6be2 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java @@ -250,7 +250,6 @@ public abstract class StdSerializer<T> * when applying contextual content converter; this is not ideal way, * but should work for most cases. */ - final AnnotationIntrospector intr = provider.getAnnotationIntrospector(); if (intr != null && prop != null) { AnnotatedMember m = prop.getMember(); @@ -259,7 +258,8 @@ public abstract class StdSerializer<T> if (convDef != null) { Converter<Object,Object> conv = provider.converterInstance(prop.getMember(), convDef); JavaType delegateType = conv.getOutputType(provider.getTypeFactory()); - if (existingSerializer == null) { + // [databind#731]: Should skip if nominally java.lang.Object + if (existingSerializer == null && !delegateType.hasRawClass(Object.class)) { existingSerializer = provider.findValueSerializer(delegateType); } return new StdDelegatingSerializer(conv, delegateType, existingSerializer); |