XStream, сериализовать Null поля в пустые теги

86
06 марта 2022, 07:00

Есть простой пример генерации XML с помощью XStream 1.4.11

@XStreamAlias("test")
class Test {
    public String firstName;
    public String secondName;
    public String lastName;
    public Test(String fname, String sname, String lname) { firstName = fname; secondName = sname; lastName = lname; }
    //.. getters and setters 
}

Может кто-то знает, как заставить при наличии Null поля генерировать пустой XML узел, а не просто выбрасывать его?

public static void main (String[] args) {
    XStream stream  = new XStream();
    stream.allowTypeHierarchy(Collection.class);
    stream.autodetectAnnotations(true);
    String xml = stream.toXML(new Test("Ivan", "Ivanov", null));
    System.out.println(xml);
}

Вывод который есть:

<test>
    <firstName>Ivan</firstName>
    <secondName>Ivanov</secondName>
</test>

Вывод, который бы хотелось получить:

<test>
    <firstName>Ivan</firstName>
    <secondName>Ivanov</secondName>
    <lastName></lastName>
</test>

P.S. Если захотите предложить что-то лучше, то одна из проблем, что всё это дело должно работать на J2SE 5.0.

Answer 1

Кривовато, немного сбивается порядок полей, но вроде как работает корректно с разнообразными типами полей.

public static void main (String[] args) {
    XStream stream  = new XStream();
    stream.allowTypeHierarchy(Collection.class);
    stream.autodetectAnnotations(true);
    stream.registerConverter(
        new TestConverter(stream.getMapper(), stream.getReflectionProvider()), 
        XStream.PRIORITY_VERY_LOW);    
    String xml = stream.toXML(new Test("Ivan", "Ivanov", null));
    System.out.println(xml);
    //Вычищаем пустые теги перед дессериализацией
    String newOne = xml.replaceAll("\\s*<(\\w+)><\\/(\\w+)>", "");
    Testform = (Test) stream.fromXML(newOne);
}

Код самого конвертера

public class TestConverter extends ReflectionConverter {
    public TestConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
        super(mapper, reflectionProvider);
    }
    @Override
    protected void doMarshal(Object source, 
                             HierarchicalStreamWriter writer, 
                             MarshallingContext context) {
        Field[] fields = source.getClass().getDeclaredFields();
        for(Field field : fields) {
            try{ 
                if(field.get(source) == null) {
                    writer.startNode(field.getName());
                    writer.setValue("");
                    writer.endNode();
                }
            } catch (Exception e) { /*логирование*/ };
        }
        super.doMarshal(source, writer, context);
    }
}
READ ALSO
Вывод целого числа из строки

Вывод целого числа из строки

Как вывести первое встречающееся целое число и следующую за ним буквуНапример ‘а6hdkfh54a’ выводит ‘6h’

128
Что можно закастить в SortedSet?

Что можно закастить в SortedSet?

Никак не могу понять, что еще можно отлить в SortedSetПерепробовал несколько типов коллекций

68
После сортировки выводит не тот элемент, который нужен

После сортировки выводит не тот элемент, который нужен

В дополнении к вопросу Что можно закастить в SortedSet?, нашел решение, но выдает другую ошибку! Почему, не могу понять

146
replaceAll и обратные слэши

replaceAll и обратные слэши

Сегодня занимался в Java проблемой кавычек в SQL запросах (инъекция) и обнаружил, что чтобы после результата функции получить \', я должен написать...

87