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);
+ }
+}