У меня есть набор модульных тестов, которые дешифруют сохраненный XML-файл в объекты JAXB. Они работали. Эти тесты использовали PowerMock (1.6.6) из-за одной детали в CUT (тестируемый код), для которого требовалось предложение «whenNew».JAXB жалуется на то, что пространство имен присутствует, когда оно должно быть там
Я решил внести изменения в абстракцию, что за фабрикой объектов, что позволило мне перейти к чистому Мокито.
Когда я это сделал, я начал получать необъяснимые проблемы при разборке XML-файлов в объекты JAXB во время теста. Он просто не хранил некоторые элементы в объектах JAXB.
Метод, который делает демаршаллинг выглядит следующим образом:
protected JAXBElement<?> unmarshallToObject(Node node, Class<?> nodeClassType) throws ServiceException {
try {
return getUnmarshaller().unmarshal(node, nodeClassType);
} catch (JAXBException ex) {
baseLogger.error(null, ex, "JAXB Exception while un-marshalling");
throw new ServiceException(UslErrCodes.BACKEND_APP.createServiceErr(BackendConfig.USL.getId(),
"JAXB Exception while un-marshalling"), ex);
}
}
Я изменил его на следующее, чтобы получить больше информации:
protected JAXBElement<?> unmarshallToObject(Node node, Class<?> nodeClassType) throws ServiceException {
try {
Unmarshaller unmarshaller = getUnmarshaller();
unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
return unmarshaller.unmarshal(node, nodeClassType);
} catch (JAXBException ex) {
baseLogger.error(null, ex, "JAXB Exception while un-marshalling");
throw new ServiceException(UslErrCodes.BACKEND_APP.createServiceErr(BackendConfig.USL.getId(),
"JAXB Exception while un-marshalling"), ex);
}
}
То, что я обнаружил, что демаршаллинг процесс отказа сохраняйте некоторые элементы в экземплярах JAXB, поскольку они получают ошибки схемы xml.
Например, после изменения этого кода я видел сообщения, подобные приведенным ниже. Я ссылаюсь здесь на пространство имен «http://namespace1.xsd», который, очевидно, не был его оригинальным именем, но все места, где это конкретное пространство имен показано в этих примерах, я использую это имя «namespace1.xsd».
JAXB Exception while un-marshalling:unexpected element (uri:"http://namespace1.xsd", local:"securityFeeRequired"). Expected elements are <{}securityFeeRequired>,<{}proprietarySegmentFlag>,<{}Treatment>,<{}creditScoreMessage>,<{}ServiceEligibility>,<{}warningMessage>,<{}creditScoreResult>,<{}creditBand>
Как вы можете видеть, документ XML указано, что элемент находится в пространстве имен, но «{}», кажется, подразумевает, что пространство имен не было ожидаемо.
Это отрывок из сгенерированного класса JAXB:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "creditScoreResult", "creditScoreMessage", "warningMessage",
"securityFeeRequired", "treatment", "creditBand", "proprietarySegmentFlag", "serviceEligibility" })
public static class FooResult implements Serializable {
private static final long serialVersionUID = 1L;
protected String creditScoreResult;
protected String creditScoreMessage;
protected String warningMessage;
protected boolean securityFeeRequired;
А вот @XmlSchema аннотаций из сгенерированного "пакет-инфо" из того же пакета:
@XmlSchema(namespace="http://namespace1.xsd", elementFormDefault=XmlNsForm.QUALIFIED)
Итак, после получения этой ошибки я решил попробовать изменить «это не возможно».
Я изменил файл XML, например, что это аналогичный отрывок:
<ExecuteFooResponse xmlns:ns1="http://namespace1.xsd" xmlns:ns2="http://namespace2.xsd">
<FooResult>
<securityFeeRequired>false</securityFeeRequired>
<Treatment><code>A001</code>
<message>No additional fee is required at this time</message>
</Treatment>
<ServiceEligibility>
<productCode>BAR</productCode>
<serviceEligibilityIndicator>true</serviceEligibilityIndicator>
</ServiceEligibility>
</FooResult>
<Response>
<ns2:code>0</ns2:code>
<ns2:description>Success</ns2:description>
</Response>
</ExecuteFooResponse>
Единственное изменение, которое я сделал был префикс пространства имен для «namespace1.xsd». Это было неудачно с «" (пробелом), что, насколько я понимаю, является правильным. Я изменил его на «ns1», но только в декларации. Я явно не ссылаюсь на этот префикс в теле элемента. Это делает тест PASS.
Пожалуйста, восстановите мое здравомыслие.