How to add ToXmlGenerator.Feature to Jackson2ObjectMapperBuilderCustomizer?

4k views Asked by At

I have the jackson bean configuration below. How can I add the ToXmlGenerator.Feature.WRITE_XML_DECLARATION feature to the builder?

The following does not work:

@Bean
public Jackson2ObjectMapperBuilderCustomizer initJackson() {
    return (builder) -> builder.modules(new JaxbAnnotationModule())
                .defaultUseWrapper(false)   
                .featuresToEnable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION); //invalid!

}

Result:

Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingJackson2XmlHttpMessageConverter' defined in class path resource [org/springframework/boot/autoconfigure/web/JacksonHttpMessageConvertersConfiguration$MappingJackson2XmlHttpMessageConverterConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter]: Factory method 'mappingJackson2XmlHttpMessageConverter' threw exception; nested exception is org.springframework.beans.FatalBeanException: Unknown feature class: com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator$Feature

My initial goal is to add the following line during deserialization:

<?xml version="1.0" encoding="UTF-8"?>.

Maybe there is a different way instead of using the ToXmlGenerator?

I also tried the following, but that does also NOT add the xml declaration line:

@Bean
@Primary
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    XmlMapper mapper = (XmlMapper) builder
            .createXmlMapper(true)
            .build();

    mapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
    return mapper;
}
1

There are 1 answers

1
membersound On BEST ANSWER

It was close, but the ObjectMapper use for serialization of java beans to xml is not the one in the question. Instead in Jackson2ObjectMapperBuilderCustomizer a new mapper is created by spring autoconfiguration. This has to be overridden as follows:

@Bean
public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(
        Jackson2ObjectMapperBuilder builder) {
    ObjectMapper mapper = builder.createXmlMapper(true).build();
    ((XmlMapper) mapper).enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION);
    return new MappingJackson2XmlHttpMessageConverter(mapper);
}