AxisFault: The endpoint reference (EPR) for the Operation not found is…

Решил написать статью, так как возился с этой проблемой несколько дней. Мы используем Axis2 для создания SOAP-сервисов. После обновления версии Axis2 до 1.7.9 все операции стали требовать обязательного присутствия HTTP-заголовка SOAPAction, что, разумеется, потенциально ломало все старые клиенты. Без указания этого заголовка возникала ошибка:

Поиск по интернету ничего не дал. Я долго пытался включать и отключать различные Dispatcher-ы и опции в “axis2.xml”, но ничего не помогало. Перечитал всю документацию на официальном сайте, но тоже ничего не нашёл. Как же быть?

Раз уж сразу ничего не выходит, то подключаем тяжёлую артиллерию. Я выкачал исходники Axis2 и Axiom, подключил их к проекту и указал в Run Configurations, что исходники при отладке нужно искать и в них тоже. После пары часов отладки ситуация стала яснее.

Что же у нас происходит? Axis2 каждый запрос пропускает через серию Dispatcher-ов, описываемых в “axis2.xml”. Каждый из них работает с определённой частью запроса. Нас интересует SOAPMessageBodyBasedDispatcher, так как именно он в нашем случае должен из тела запроса узнавать, какая операция должна выполниться.

Обратите внимание на метод findOperation:

В самое первой строке метода он пытается получить имя первого элемента внутри body, у элемента envelope. Envelope и body — это стандартные элементы запроса SOAP. А дальше на основе полученного названия элемента определяется выполняемая операция. Однако, если вы в отладке зайдёте внутрь, то вы заметите, что происходит путаница, и метод getSOAPBodyFirstElementLocalName в реальности получает не первый дочерний элемент body, а сам envelope. А по названию “envelope” он, разумеется, никак не может определить операцию.

Явно какая-то ошибка. Поискал в Google и нашёл в трекере задач Axis2 точь в точь нашу ошибку. Да, это самая настоящая ошибка внутри Axis2. И она ещё не исправлена. Там же предлагается вариант обхода проблемы. Так вот. Проблема в том, что Axis2 может работать как с REST, так и с SOAP. В данном случае он ошибочно начинает считать, что наш запрос не SOAP, а REST, в результате возвращает нам самый первый элемент, минуя структуры запроса SOAP. Мы можем просто отключить поддержку REST в “axis2.xml” вот таким образом:

После этого можно отправлять все запросы так же, как и в старых версиях Axis2 без указания HTTP-заголовка SOAPAction.

Вам также может потребоваться избавиться от ошибки https is forbidden, которая у меня была до этого.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *