How should I configure Jackson to produce XML using the @XmlRootElement on list items

不羁岁月 提交于 2019-12-18 09:36:23

问题


I have a Spring-MVC @RestController that uses generic names rather than the names I have configured with @XmlRootElement or @JacksonXmlRootElement. I want XML to look like this:

<list>
  <foo>
    <name>John</name>
  </foo>
</list>

but I get the following:

<ArrayList>
  <item>
    <name>John</name>
  </item>
</ArrayList>

Marshalling a single instance correctly looks like this:

<foo>
  <name>John</name>
</foo>

To try and solve this, I've tried using both Jackson and JAXB annotations. I've also conducted an extensive search for someone else's solution on Stack Overflow, various blogs, and issues reported against Jackson and Spring-mvc.

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.junit.Test;    
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;

public class JacksonXmlTest {

    @XmlRootElement(name="foo")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Foo {
        private String name;

        public Foo(String name) {
            setName(name);
        }

        public String getName() {
            return name;
        }

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

    @Test
    public void understandListTest() throws JsonProcessingException {
        // This is a JUnit test.....
        List<Foo> fooList = new ArrayList<>();
        fooList.add(new Foo("John"));

        XmlMapper mapper = new XmlMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.registerModule(new JaxbAnnotationModule());
        System.err.println(mapper.writeValueAsString(fooList));
        System.err.println();
        System.err.println(mapper.writeValueAsString(fooList.get(0)));
    }

}

Please help me configure jackson to output the list wrapped in "list" tags and have each Foo object contained in "foo" tags rather than "item" tags.


回答1:


You should create a class ListFoo that contains a list of Foo Object:

@XmlRootElement(name="list")
@XmlAccessorType(XmlAccessType.FIELD)
public class ListFoo {

    @XmlElement(name = "foo")
    private List<Foo> listFoo;

    // getters & setters

 }



回答2:


Using MixIn feature you can define name for an ArrayList class and others from java.util.*.

import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class XmlMapperApp {

    public static void main(String[] args) throws Exception {
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.addMixIn(ArrayList.class, ArrayListMixIn.class);
        xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);

        List<Item> items = new ArrayList<>();
        items.add(new Item());
        items.add(new Item());
        System.out.println(xmlMapper.writeValueAsString(items));
    }
}

@JacksonXmlRootElement(localName = "list")
interface ArrayListMixIn {
}

class Item {

    private String name = "random - " + ThreadLocalRandom.current().nextDouble();

    public String getName() {
        return name;
    }

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

Above code prints:

<list>
  <item>
    <name>random - 0.2256442724594785</name>
  </item>
  <item>
    <name>random - 0.9958813192003821</name>
  </item>
</list>


来源:https://stackoverflow.com/questions/57596464/how-should-i-configure-jackson-to-produce-xml-using-the-xmlrootelement-on-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!