Jackson 使用 dropwizard 生成空的 XML,但不在单元测试中

Jackson producing empty XML with dropwizard but not in unit test

我发现一些用

注释的字段有问题
@JsonSerialize 

当周围的 class 从 web-service 作为 XML 返回时,但不在单元测试中。当使用 Accept header of "application/json" 调用服务时,一切正常。当使用 "application/xml" 的 Accept header 调用服务时,指定序列化程序的字段将被空 XML 标记存根。

示例代码(从实际问题中简化而来)。

public abstract class AbstractEntity {
    private String name;

    @JsonSerialize(using = MyStampSerializer.class)
    private MyStamp created;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MyStamp getCreated() {
        return this.created;
    }

    public void setCreated(MyStamp created) {
        this.created = created;
    }
}

@Immutable
@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement(name = "entity")
public class Entity extends AbstractEntity {

    public Entity() {
        super();
    }        
}

public class MyStampSerializer extends JsonSerializer<RegistryStamp>
{
    @Override
    public void serialize(MyStamp stamp, JsonGenerator jgen, SerializerProvider provider) 
        throws IOException
    {
        jgen.writeStartObject();
        jgen.writeStringField("name", stamp.getName());
        jgen.writeNumberField("timestamp", stamp.getTimestamp().getMillis());
        jgen.writeEndObject();
    }
}

public class EntityXMLTest {

    @Test
    public void serializeAndDeserializeTest() throws InvalidClassificationException, JsonProcessingException, IOException, InvalidNameException {
        Entity entity = buildTestEntity();  // Code not included.
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.registerModule(new RegistryModule());
        String xml = xmlMapper.writeValueAsString(collection);
        assertNotNull(xml);
        assertThat(xml, is("Hello"));
    }
}

所以在 web-service 请求 xml 的情况下,(不正确的)输出看起来像:

<entity>
    <name>theName</name>
    <created />
</entity>

但是在单元测试中,(正确的)输出看起来像:

<entity>
    <name>theName</name>
    <created>
        <name>otherName</name>
        <timestamp>8647567</timestamp>
    </created>
</entity>

JSON 在单元测试和 web-service.

中都符合预期

如果我注释掉序列化程序和 re-run 单元测试,输出如下:

<entity>
    <created>
        <name>test1</name>
        <timestamp>
            <dayOfYear>2</dayOfYear>
            <dayOfMonth>2</dayOfMonth>
            <dayOfWeek>5</dayOfWeek>
            <era>1</era>
            <year>1970</year>
            <weekOfWeekyear>1</weekOfWeekyear>
            <!-- snip ..... etc -->
        </timestamp>
    </created>
</entity>

所以我们显然需要序列化程序来申请 XML 以及当我在单元测试中直接调用 XMLMapper 时发生的情况。

有什么方法可以告诉 Jersery/Jackson 对 XML 和 JSON 使用序列化器吗?有没有办法找出杰克逊为什么用自定义序列化程序为字段添加 XML ?此外,有没有一种方法可以配置单元测试,使其与 dropwizard/Jersey/Jackson web-service?

的行为相同

最终我成功了。要点是:

如果你想将@JsonSerialize 与 jackson 和 dropwizard 一起使用,你可能需要使用 dropwizard-xml extension bundle that is mentioned at the very bottom of the jackson annotations page

在此之后,需要进行一些更改才能使 XML 看起来正确,主要涉及

@JacksonXmlProperty and 
@JacksonXmlElementWrapper

最后的挑战是找到与我使用的 jackson 版本兼容的 dropwizard-xml 版本, 使用 java 1.7 编译我发现 0.9.0-30 有用。