【问题标题】:Jackson producing empty XML with dropwizard but not in unit testJackson 使用 dropwizard 生成空 XML,但不在单元测试中
【发布时间】:2017-02-07 05:13:08
【问题描述】:

我发现一些已用

注释的字段存在问题
@JsonSerialize 

当周围的类作为 XML 从 Web 服务返回时,但不在单元测试中。当使用“application/json”的 Accept 标头调用服务时,一切正常。当使用“application/xml”的 Accept 标头调用服务时,指定序列化程序的字段将使用空 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 服务请求 xml,则(不正确的)输出如下所示:

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

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

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

JSON 在单元测试和网络服务中都符合预期。

如果我注释掉序列化程序并重新运行单元测试,输出如下所示:

<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 网络服务相同?

【问题讨论】:

  • 那么,我是否理解正确:您希望 xml 序列化也显示创建时间?
  • @pandaadb 是的。我已经编辑了这个问题,让它更清楚一点。
  • 对不起,我还没有开始写答案:/您的问题可能与 DW 初始化其对象映射器的方式有关。您可以首先尝试查找 xml 内容类型的消息正文编写器,然后逐步完成该编写器。我希望我能尽快检查那里发生的事情,然后回答:)

标签: java json xml jackson dropwizard


【解决方案1】:

最终我得到了它的工作。重点是:

如果您想将@JsonSerialize 与jackson 和dropwizard 一起使用,您可能需要使用jackson annotations page 最底部提到的dropwizard-xml 扩展包

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

@JacksonXmlProperty and 
@JacksonXmlElementWrapper

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多