javaxmlspring-bootjacksonjackson-dataformat-xml

Annotation based XML Marshalling in Spring Boot


In my spring boot application, I have below DTO class

@Data
public clsss Feed {
    private int id;
    private String name;
    private String title;
    
    @Builder
    @XmlRootElement(name = "feeds")
    public static class Feeds {
        @XmlElement(name = "feed")
        @Singular
        private List<Feed> feeds;
    }
}

My config class as below

@Component
public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.modulesToInstall(new JaxbAnnotationModule());
    }
}

DAO class implementation as below

public Feeds getAll() {
    String sqlQuery = "SELECT * FROM feed WHERE trash = 0";
    return Feeds.builder().feeds(namedParameterJdbcTemplate.query(sqlQuery, new BeanPropertyRowMapper<>(Feed.class))).build();
}

Using my ReST API, XML response I am receiving as below:

<feeds>
    <feed>
        <feed>
            <id>1</id>
            <name>Val1</name>
            <title>Title1</title>
        </feed>
        <feed>
            <id>2</id>
            <name>Val2</name>
            <title>Title2</title>
        </feed>
    </feed>
</feeds>

I want to remove <feed> which comes as a wrapper element. Desired output is as below:

<feeds>
    <feed>
        <id>1</id>
        <name>Val1</name>
        <title>Title1</title>
    </feed>
    <feed>
        <id>2</id>
        <name>Val2</name>
        <title>Title2</title>
    </feed>
</feeds>

Solution

  • Make changes in the config class to set the default wrapper to false.

    @Component
    public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
        @Override
        public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
            jacksonObjectMapperBuilder.modulesToInstall(new JaxbAnnotationModule());
            jacksonObjectMapperBuilder.defaultUseWrapper(false);  //This was missing before
        }
    }