Потеря элемента типа при сериализации объекта внутри ArrayList в XML

Кажется, у меня возникла проблема при использовании Jackson для сериализации в XML. Мой код ниже:

ТЕСТОВЫЙ КОНТЕЙНЕР

package com.test;

import java.util.ArrayList;

import com.fasterxml.jackson.annotation.JsonProperty;

public class TestContainer {

    private String testContainerID;
    private String testContainerMessage;
    private ArrayList<TestChild> testContainerChildren;

    @JsonProperty("TestContainerID")
    public String getTestContainerID() {
        return testContainerID;
    }

    @JsonProperty("TestContainerID")
    public void setTestContainerID(String testContainerID) {
        this.testContainerID = testContainerID;
    }

    @JsonProperty("TestContainerMessage")
    public String getTestContainerMessage() {
        return testContainerMessage;
    }

    @JsonProperty("TestContainerMessage")
    public void setTestContainerMessage(String testContainerMessage) {
        this.testContainerMessage = testContainerMessage;
    }

    @JsonProperty("TestContainerChildren")
    public ArrayList<TestChild> getTestContainerChildren() {
        return testContainerChildren;
    }

    @JsonProperty("TestContainerChildren")
    public void setTestContainerChildren(ArrayList<TestChild> testContainerChildren) {
        this.testContainerChildren = testContainerChildren;
    }

}

ТЕСТЧИЛД

package com.test;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName(value="TestChild")
public class TestChild {

    private String testChildID;
    private String testChildMessage;

    @JsonProperty("TestChildID")
    public String getTestChildID() {
        return testChildID;
    }

    @JsonProperty("TestChildID")
    public void setTestChildID(String testChildID) {
        this.testChildID = testChildID;
    }

    @JsonProperty("TestChildMessage")
    public String getTestChildMessage() {
        return testChildMessage;
    }

    @JsonProperty("TestChildMessage")
    public void setTestChildMessage(String testChildMessage) {
        this.testChildMessage = testChildMessage;
    }

}

ИСПОЛЬЗОВАНИЕ

  • Сериализация:

    XmlMapper xm = новый XmlMapper (); TestContainer tc = xm.readValue (sb.toString (), TestContainer.class);

  • Десериализация:

    System.out.println (xm.writeValueAsString (tc)); tc = xm.readValue (sb.toString (), TestContainer.class);

Я загружаю XML-файл из папки в пути к классам и помещаю содержимое файла в StringBuffer. Проблема заключается в сгенерированном XML для коллекции объектов. При написании XML мне нужно что-то вроде:

<TestContainerChildren><TestChild><...(Element Details)...></TestChild></TestContainerChildren>

но я получаю:

<TestContainerChildren><TestContainerChildren><...(Element Details)...><TestContainerChildren></TestContainerChildren>

Я не уверен, что мне здесь не хватает. У меня нет проблем с JSON-частью сериализации / десериализации, только XML. Я пробовал использовать аннотации Джексона и JAXB, чтобы отключить упаковку, я пробовал использовать следующие аннотации:

  • @JsonRootName
  • @JsonProperty
  • @JacksonXmlElementWrapper
  • @JacksonElement
  • @XmlElementWrapper
  • @XmlElement

Я почти уверен, что это что-то глупое с моей стороны, но любая помощь будет очень признательна.


person Prmths    schedule 03.08.2013    source источник
comment
Я не понимаю, как все атрибуты сериализуются нормально. Это просто имя класса дочерних элементов, которые не сериализуются. Я думал, что проблема может быть в стирании типа Java, но если процессор не может найти тип, я не думаю, что он может прочитать строку XML, поскольку он не сможет создать экземпляр класса TestChild.   -  person Prmths    schedule 08.08.2013
comment
Ссылка на SSCCE: sugarsync.com/pf/D7626132_721_921097897   -  person Prmths    schedule 08.08.2013
comment
ОБНОВЛЕНИЕ: после попытки следовать указаниям по следующим вопросам stackoverflow.com/questions/2525042/ stackoverflow.com/questions/6846244/ stackoverflow.com/questions/9829403/ stackoverflow.com/questions/15430715/ Я до сих пор не нашел работающего решения. Я думаю о настраиваемом сериализаторе, но не знаю, нужно ли мне это.   -  person Prmths    schedule 13.08.2013


Ответы (2)


Хорошо, пара заметок. Во-первых, @JsonRootName влияет только на имя, используемое для корня XML-документа, как следует из имени. Таким образом, он не используется для TestChild. Во-вторых, похоже, что вы хотите использовать так называемый «развернутый» вывод для списков, опуская элемент для свойства, содержащего элементы списка. Это можно сделать с помощью:

@JacksonXmlElementWrapper(useWrapping=false)
@JsonProperty("TestContainerChildren")
public ArrayList<TestChild> getTestContainerChildren() { ... }

поскольку по умолчанию используется оболочка (она отличается от JAXB, где по умолчанию используется развертка). Или, если вы хотите изменить это глобально, чтобы оно было развернуто по умолчанию, вы можете изменить значения по умолчанию с помощью XmlModule:

JacksonXmlModule module = new JacksonXmlModule();
// to default to using "unwrapped" Lists:
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);

Надеюсь это поможет!

person StaxMan    schedule 05.08.2013
comment
Спасибо за ваш ответ. Я удалил аннотацию @JsonRootName, вы были правы. Я хочу сохранить элемент контейнера. Я работаю над чем-то вроде того, что вы видите в XML здесь. Как видите, элементы Endpoint и Format заключены в свои соответствующие элементы. - person Prmths; 06.08.2013

Я получил эту работу, используя следующие аннотации над объявлением переменной:

  • @JacksonXmlElementWrapper (localName = "[вставить название коллекции]")
  • @JacksonXmlProperty (localName = "[вставить имя элемента коллекции]")

Это был простой случай RTFM, поскольку он задокументирован здесь.

person Prmths    schedule 30.08.2013