Сериализация FasterXML без использования типа поля в XML

Я пытаюсь добиться следующего XML:

<model>
    <entry>
        <key>A</key>
        <value>1</value>
    </entry>
    <entry>
        <key>B</key>
        <value>2</value>
    </entry>
</model>

Самая близкая модель POJO, которую я получил, экспериментируя с моим кодом, выглядит так:

import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import static com.google.common.collect.Lists.newArrayList;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.junit.Test;

public class InsPersonFormTest {

    @JsonRootName("model")
    public static class Model extends ArrayList<Entry> {

        public Model(List<Entry> entries) { super(entries); }

        public List<Entry> getEntry() { return this; }
    }

    public static class Entry {

        String key;
        String value;

        public Entry(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getKey() { return key; }

        public String getValue() { return value; }       
    }

    @Test
    public void shouldSendPostRequest() throws JsonProcessingException {
        Model model = new Model(newArrayList(new Entry("A", "1"), new Entry("B", "2")));

        ObjectMapper xmlMapper = new XmlMapper();
        String xml = xmlMapper.writeValueAsString(model);

        assertThat(xml, equalTo(
                "<model>"
                + "<entry><key>A</key><value>1</value></entry>"
                + "<entry><key>B</key><value>2</value></entry>"
                + "</model>"));
    }
}

Но это дает мне

Ожидаемое:

"<model><entry><key>A</key><value>1</value></entry><entry><key>B</key><value>2</value></entry></model>"

но: было

"<model><item><key>A</key><value>1</value></item><item><key>B</key><value>2</value></item></model>"

Как я могу изменить item в entry или используйте простую структуру POJO с более подходящей Map<String, String> поле?

2 ответа

Решение

Не делай своего Model Класс подтип ArrayList, Вместо этого используйте композицию

public static class Model {
    private ArrayList<Entry> entry;

    public Model(List<Entry> entries) {
        entry = entries; // or make a copy 
    }

    @JacksonXmlElementWrapper(useWrapping = false)
    public List<Entry> getEntry() {
        return entry
    }

}

ArrayList это List и ручки Джексона List управляемым способом.

Вам нужно будет добавить JacksonXmlElementWrapper так что вы можете сказать Джексону не оборачивать полученный XML.

Вы можете использовать

@JacksonXmlRootElement(/* custom */)

комментировать Entry и добавьте локальное имя узла XML и значение пространства имен.

Вы пытались аннотировать вступительный класс?

@JsonRootName("entry")
public static class Entry {

    String key;
    String value;

    public Entry(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() { return key; }

    public String getValue() { return value; }       
}
Другие вопросы по тегам