Принятие у меня есть схема, которая описывает корневой класс элемента Root
это содержит a List<Entry>
где Entry
класс имеет имя обязательного поля.
Вот то, как это смотрит в коде:
@XmlRootElement
class Root{
@XmlElement(name="entry")
public List<Entry> entries = Lists.newArrayList();
}
@XmlRootElement
class Entry{
@XmlElement(name="name",required=true)
public String name;
}
Если я предоставляю следующий XML для немаршалинга:
<root>
<entry>
<name>ekeren</name>
</entry>
<entry>
</entry>
</root>
У меня есть проблема, потому что вторая запись не содержит имя. Таким образом, неМаршалл производит null
.
Есть ли способ настроить JAXB в неМаршалл a Root
объект, который будет только содержать "хорошую" запись?
Вы можете добавить магический метод afterUnmarshal, чтобы позаботиться о пустых записях:
@XmlRootElement
class Root{
@XmlElement(name="entry")
public List<Entry> entries = Lists.newArrayList();
void afterUnmarshal(final Unmarshaller unmarshaller, final Object parent) {
Iterator<Entry> iter = entries.iterator();
while (iter.hasNext()) {
if (iter.next().name == null) iter.remove();
}
}
}
EDIT:
Не уверен, что это лучше подходит для вас, но, возможно, это поможет. Вы также можете использовать Pacher, например, если не все объекты, необходимые для исправления/подтверждения результата, доступны в afterUnmarshal(...)
Выполняется UnmarshallingContext после завершения парсинга. В основном используется для разрешения прямых IDREF, но может выполнять любое действие. (javadoc)
Вот пример:
@XmlRootElement
class Entry{
@XmlElement(name="name",required=true)
public String name;
private boolean isValidEntry() {
return name != null;
}
void afterUnmarshal(final Unmarshaller unmarshaller, final Object parent) {
if (!isValidEntry()) {
// entry not yet added to parent - use a patcher
UnmarshallingContext.getInstance().addPatcher(new Patcher() {
public void run() throws SAXException {
((Root)parent).removeEntry(this);
}
});
}
}
}
Однако я бы не стал слишком злоупотреблять этим, не только потому, что это API только для Sun.
Но если вам действительно нужно что-то настраиваемое, что не является частью кода самих маршалируемых объектов. Возможно, лучше посмотреть на что-то после размаршалинга. Интересно, не подойдет ли вам Bean Validation (JSR 303), например, использование Hibernate Validator (не пугайтесь названия, вам не нужен Hibernate ORM для его использования). Сам я его не использовал, но использование (нового) стандарта для валидации звучит разумно, не так ли?