FasterXML / jackson-databind

General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)
Apache License 2.0
3.53k stars 1.38k forks source link

Converted object serialized with BeanSerializer instead of the configured serializer #359

Closed fschopp closed 10 years ago

fschopp commented 10 years ago

Jackson version: 2.3.0

In the example below, a list of Cs should be serialized by converting each C to an A. Unfortunately, Jackson uses the BeanSerializer for the conversion results instead of the serializer configured for A.

@JsonSerialize(using = ASerializer.class)
static class A {
    public String unexpected = "Bye.";
}

static class B {
    @JsonSerialize(as = List.class, contentAs = C.class)
    public List<C> list = Arrays.asList(new C());
}

@JsonSerialize(converter = CtoAConverter.class)
static class C { }

static class CtoAConverter extends StdConverter<C, A> {
    @Override
    public A convert(C value) {
        return new A();
    }
}

static class ASerializer extends JsonSerializer<A> {
    @Override
    public void serialize(A a, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
        jsonGenerator.writeStartArray();
        jsonGenerator.writeString("Hello world.");
        jsonGenerator.writeEndArray();
    }
}

@Test
void testBSerialization() throws Exception {
    System.out.println(new ObjectMapper().writeValueAsString(new B()));
}

Actual output:

{"list":[{"unexpected":"Bye."}]}

Expected output:

{"list":[["Hello world."]]}
cowtowncoder commented 10 years ago

One possible reason here is the precedence of @JsonSerialize annotations (property one has higher priority, masking one from class declaration) -- it is possible that "converter" from class is effectively ignored.

Thank you for unit test for this and other bug reports!

cowtowncoder commented 10 years ago

Turns out code just needed to re-check for existence of @JsonSerialize(using=...) after target type was detected. Will be included in 2.4.0.