Ранее в этом месяце я представил концепцию Mule, которая требовала использования фильтра проверки схемы . Вариант использования был довольно простым. XML-сообщения поступают через SOAP-запрос, и некоторые поля во входящем сообщении должны были проверяться по множеству XML-схем.
Что ж, это идеальный сценарий использования для Schema Validator, который поставляется вместе с Mule. Это элемент, который вы можете выбросить из палитры Mule Studio прямо в ваш поток.
Конфигурация этого элемента немного сложнее. Это принимает разделенный запятыми список схем для проверки полезной нагрузки. Справедливо, но вы сразу же столкнулись с первой проблемой. Как найти URL, который работает как в Mule Studio, так и в автономном Mule, если ваши схемы являются частью classpath?
Обычно в Spring вы делаете это, предварительно ожидая ваш URL с помощью « classpath:» . К сожалению, это не работает с этим фильтром. Мы решили проблему, поместив схемы в папку src / main / resources в Mule Studio. Из фильтра проверки схемы мы ссылались на них с помощью переменной $ {app.home} :
<mulexml:schema-validation-filter schemaLocations="${app.home}/classes/MyXsd1_v2.1.0.xsd,${app.home}/classes/xsd/MyXsd2_v1.2.0.xsd" returnResult="true"/>
Вторая проблема, которая сразу же возникает, заключается в том, что средство проверки схемы успешно игнорирует любые
xs: import или
xs: include в ваших схемах. При запуске средства проверки схемы произойдет сбой, исключение будет выглядеть примерно так (подробности об исключении удалены для простоты).
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'schemaValidator': Invocation of init method failed; nested exception is org.mule.api.lifecycle.InitialisationException: src-resolve: Cannot resolve the name 'xxxyyy' to a(n) 'type definition' component. ... Caused by: org.mule.api.lifecycle.InitialisationException: src-resolve: Cannot resolve the name 'xxxyyy' to a(n) 'type definition' component. ... Caused by: org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'xxxyyy' to a(n) 'type definition' component. ...
Это связано с классом;
javax.xml.validation.SchemaFactory . Фильтр проверки схемы Mule использует этот класс для построения схем, чтобы иметь возможность проверки. Этот фабричный класс игнорирует любые XSD «include» и «import». (Смотрите
здесь для получения дополнительной информации.)
К счастью, есть решение. Фильтр проверки схемы Mule позволяет вам настраивать собственный распознаватель ресурсов. Это класс, который используется для загрузки внешних ресурсов, например XSD «включает» и «импортирует». Мы написали очень простой распознаватель ресурсов, который загружает внешние ресурсы из пути к классам:
package com.ricston.xml; import java.io.IOException; import java.io.InputStream; import org.apache.xerces.dom.DOMInputImpl; import org.mule.util.IOUtils; import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; public class ClasspathResourceResolver implements LSResourceResolver { @Override public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { try { InputStream resource = IOUtils.getResourceAsStream(systemId, getClass()); return new DOMInputImpl(publicId, systemId, baseURI, resource, null); } catch (IOException e) { e.printStackTrace(); return null; } } }
Как видите, это предельно просто. Всего 2 строки кода Java. Идея в том, что мы загружаем внешний ресурс, переданный SchemaFactory, с помощью библиотеки Mule IOUtils. После загрузки мы должны передать обратно экземпляр
org.w3c.dom.ls.LSInput . Мы использовали
org.apache.xerces.dom.DOMInputImpl, чтобы помочь нам в этом.
Последний шаг теперь состоит в том, чтобы настроить фильтр проверки схемы для использования нашего пользовательского распознавателя ресурсов:
<spring:bean id="classpathResourceResolver" name="classpathResourceResolver" class="com.ricston.xml.ClasspathResourceResolver"/> <mulexml:schema-validation-filter schemaLocations="${app.home}/classes/MyXsd1_v2.1.0.xsd,${app.home}/classes/xsd/MyXsd2_v1.2.0.xsd" returnResult="true" resourceResolver-ref="classpathResourceResolver"/>
Конечно, вы можете написать свой собственный загрузчик ресурсов для загрузки ресурсов из абсолютных путей, относительных путей или любого другого метода, который вы хотели бы реализовать. Достаточно просто взять наш
ClasspathResourceResolver и преобразовать его в соответствии с вашими потребностями.
Еще одна проблема, с которой я столкнулся при использовании этого фильтра, — это способ его обработки. Если вы предоставите ему XML, который не соответствует какой-либо схеме, он молча блокирует ваше сообщение. По умолчанию в журналах ничего не отображается. Чтобы увидеть ошибки, вам нужно настроить класс SchemaValidationFilter для входа на уровень отладки через log4j:
log4j.logger.org.mule.module.xml.filters.SchemaValidationFilter=DEBUG
Мы закончим этот пост в блоге, сказав, что готовый фильтр проверки схемы Mule весьма полезен по очевидным причинам, но для использования его полного потенциала требуется немного работы по настройке.