Fix [JACKSON-829]
diff --git a/release-notes/CREDITS b/release-notes/CREDITS index a595d7a..55cab1b 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS
@@ -890,3 +890,7 @@ * Reported [JACKSON-806]: REQUIRE_SETTERS_FOR_GETTERS ignores explicitly annotated getters [1.9.6] +James Roper: + * Reported [JACKSON-829] Custom serializers not working for List<String> + properties, @JsonSerialize(contentUsing) + [1.9.7]
diff --git a/release-notes/VERSION b/release-notes/VERSION index 6a8b59b..883816d 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION
@@ -10,6 +10,9 @@ * [Issue-11] JsonParser.getValueAsLong() returning int, not long (reported by Daniel L) + * [JACKSON-829] Custom serializers not working for List<String> properties, + @JsonSerialize(contentUsing) + (reported by James R) ------------------------------------------------------------------------ === History: ===
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/BasicSerializerFactory.java b/src/mapper/java/org/codehaus/jackson/map/ser/BasicSerializerFactory.java index e36e23c..5f6f418 100644 --- a/src/mapper/java/org/codehaus/jackson/map/ser/BasicSerializerFactory.java +++ b/src/mapper/java/org/codehaus/jackson/map/ser/BasicSerializerFactory.java
@@ -7,6 +7,7 @@ import java.util.*; import org.codehaus.jackson.map.*; +import org.codehaus.jackson.map.annotate.JacksonStdImpl; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.map.ext.OptionalHandlerFactory; import org.codehaus.jackson.map.introspect.*; @@ -489,13 +490,13 @@ Class<?> elementRaw = type.getContentType().getRawClass(); if (isIndexedList(raw)) { if (elementRaw == String.class) { - return new IndexedStringListSerializer(property); + return new IndexedStringListSerializer(property, elementValueSerializer); } return StdContainerSerializers.indexedListSerializer(type.getContentType(), staticTyping, elementTypeSerializer, property, elementValueSerializer); } if (elementRaw == String.class) { - return new StringCollectionSerializer(property); + return new StringCollectionSerializer(property, elementValueSerializer); } return StdContainerSerializers.collectionSerializer(type.getContentType(), staticTyping, elementTypeSerializer, property, elementValueSerializer);
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/std/IndexedStringListSerializer.java b/src/mapper/java/org/codehaus/jackson/map/ser/std/IndexedStringListSerializer.java index c17fba3..af53043 100644 --- a/src/mapper/java/org/codehaus/jackson/map/ser/std/IndexedStringListSerializer.java +++ b/src/mapper/java/org/codehaus/jackson/map/ser/std/IndexedStringListSerializer.java
@@ -15,13 +15,11 @@ import org.codehaus.jackson.map.annotate.JacksonStdImpl; /** - * Efficient implement for serializing {@link List}s that contains Strings and are random-accessible. + * Efficient implementation for serializing {@link List}s that contains Strings and are random-accessible. * The only complexity is due to possibility that serializer for {@link String} * may be overridde; because of this, logic is needed to ensure that the default * serializer is in use to use fastest mode, or if not, to defer to custom * String serializer. - * - * @since 1.7 */ @JacksonStdImpl public final class IndexedStringListSerializer @@ -31,9 +29,15 @@ protected JsonSerializer<String> _serializer; public IndexedStringListSerializer(BeanProperty property) { - super(List.class, property); + this(property, null); } + @SuppressWarnings("unchecked") + public IndexedStringListSerializer(BeanProperty property, JsonSerializer<?> ser) { + super(List.class, property); + _serializer = (JsonSerializer<String>) ser; + } + @Override protected JsonNode contentSchema() { return createSchemaNode("string", true); } @@ -42,9 +46,11 @@ @Override public void resolve(SerializerProvider provider) throws JsonMappingException { - JsonSerializer<?> ser = provider.findValueSerializer(String.class, _property); - if (!isDefaultSerializer(ser)) { - _serializer = (JsonSerializer<String>) ser; + if (_serializer == null) { + JsonSerializer<?> ser = provider.findValueSerializer(String.class, _property); + if (!isDefaultSerializer(ser)) { + _serializer = (JsonSerializer<String>) ser; + } } }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/std/StringCollectionSerializer.java b/src/mapper/java/org/codehaus/jackson/map/ser/std/StringCollectionSerializer.java index 1561cdd..7a32fca 100644 --- a/src/mapper/java/org/codehaus/jackson/map/ser/std/StringCollectionSerializer.java +++ b/src/mapper/java/org/codehaus/jackson/map/ser/std/StringCollectionSerializer.java
@@ -20,21 +20,25 @@ * may be overridde; because of this, logic is needed to ensure that the default * serializer is in use to use fastest mode, or if not, to defer to custom * String serializer. - * - * @since 1.7 */ @JacksonStdImpl - public class StringCollectionSerializer extends StaticListSerializerBase<Collection<String>> implements ResolvableSerializer { protected JsonSerializer<String> _serializer; + @Deprecated public StringCollectionSerializer(BeanProperty property) { - super(Collection.class, property); + this(property, null); } - + + @SuppressWarnings("unchecked") + public StringCollectionSerializer(BeanProperty property, JsonSerializer<?> ser) { + super(Collection.class, property); + _serializer = (JsonSerializer<String>) ser; + } + @Override protected JsonNode contentSchema() { return createSchemaNode("string", true); } @@ -43,9 +47,11 @@ @Override public void resolve(SerializerProvider provider) throws JsonMappingException { - JsonSerializer<?> ser = provider.findValueSerializer(String.class, _property); - if (!isDefaultSerializer(ser)) { - _serializer = (JsonSerializer<String>) ser; + if (_serializer == null) { + JsonSerializer<?> ser = provider.findValueSerializer(String.class, _property); + if (!isDefaultSerializer(ser)) { + _serializer = (JsonSerializer<String>) ser; + } } }
diff --git a/src/test/org/codehaus/jackson/map/ser/TestJsonSerialize3.java b/src/test/org/codehaus/jackson/map/ser/TestJsonSerialize3.java new file mode 100644 index 0000000..ba90223 --- /dev/null +++ b/src/test/org/codehaus/jackson/map/ser/TestJsonSerialize3.java
@@ -0,0 +1,43 @@ +package org.codehaus.jackson.map.ser; + +import java.io.IOException; +import java.util.*; + +import org.codehaus.jackson.*; +import org.codehaus.jackson.map.*; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +public class TestJsonSerialize3 extends BaseMapTest +{ + // [JACKSON-829] + static class FooToBarSerializer extends JsonSerializer<String> { + @Override + public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { + if ("foo".equals(value)) { + jgen.writeString("bar"); + } else { + jgen.writeString(value); + } + } + } + + static class MyObject { + @JsonSerialize(contentUsing = FooToBarSerializer.class) + List<String> list; + } + /* + /********************************************************** + /* Test methods + /********************************************************** + */ + + public void testCustomContentSerializer() throws Exception + { + ObjectMapper m = new ObjectMapper(); + MyObject object = new MyObject(); + object.list = Arrays.asList("foo"); + String json = m.writeValueAsString(object); + assertEquals("{\"list\":[\"bar\"]}", json); + } +}