Какие средства используются для парсинга SOAP XML
Что проверяют
Различаете ли вы уровни работы с SOAP: разбор XML как такового, работу с конвертом и привязку к объектам по WSDL. Следом часто спрашивают, как вы защитились от XXE и что выбрать для очень больших ответов.
Как отвечать
- DOM:
DocumentBuilderFactoryстроит дерево в памяти, удобно для небольших сообщений и выборки черезjavax.xml.xpath; - SAX: событийный разбор с колбэками, память почти не расходуется, но состояние приходится вести вручную;
- StAX:
XMLStreamReader, потоковый pull-разбор. Код проще, чем на SAX, подходит для огромных ответов; - SAAJ:
jakarta.xml.soap(MessageFactory,SOAPMessage,SOAPBody,SOAPFault) работает именно с конвертом, заголовками и вложениями; - Jakarta XML Binding (бывший JAXB): превращает XML в объекты и обратно, классы генерируются из XSD или WSDL через
xjcили Maven-плагин; - JAX-WS и фреймворки: Apache CXF (
wsdl2java,JaxWsProxyFactoryBean) и Spring Web Services сWebServiceTemplateиJaxb2Marshaller. Они сами разбирают конверт, превращают fault в исключение и отдают готовый объект.
Для современного стека важно: JAXB и JAX-WS убраны из JDK в Java 11. Теперь это отдельные зависимости с пакетом jakarta.xml.bind, и импорты javax.xml.bind из старых примеров в Spring Boot 3 не заработают.
Скажите про безопасность: стандартный парсер по умолчанию обрабатывает DTD и внешние сущности, поэтому включают disallow-doctype-decl, как рекомендует OWASP. Иначе ответ чужого сервиса может прочитать файл с вашего диска. И про версии: у SOAP 1.1 и 1.2 разные пространства имён конверта и Content-Type (text/xml против application/soap+xml).
Где спотыкаются
Берут DocumentBuilderFactory с настройками по умолчанию. Пока не вызван setNamespaceAware(true), пространства имён не учитываются, и поиск Body по namespace молча ничего не находит.
Разбирают ответ регулярками и строковыми операциями. Первый же другой префикс пространства имён или CDATA ломают код.
Грузят в DOM многомегабайтные ответы с вложениями. Для них подходят StAX и MTOM, который выносит бинарные данные из тела сообщения.