Мне кажется, это немного странно - у меня есть очень простая SOAP-служба, созданная Spring-WS, которая развертывает & работает очень хорошо внутри контейнера Tomcat 7. Я экспериментировал с Glassfish 4 в последнее время и пытался заставить эту службу SOAP работать, но каждый раз, когда я пытаюсь протестировать вызов через SoapUI, получаю "405 метод не разрешен".
Есть ли у кого-нибудь советы о том, что может вызвать это? Это то же самое, что и WAR, развернутое в обоих контейнерах - единственное изменение, которое я сделал, - это настройка для моего поиска JNDI-данных в моем сервисе, все остальное идентично.
Странно, что при развертывании в Glassfish он будет обслуживать WSDL (то есть localhost:8080/user-soap-service/user.wsdl
), поэтому я знаю, что приложение развернуто/прослушивается по этому URL-адресу просто отказывается пропускать какие-либо POST через это.
Это мой web.xml:
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>user-soap-service</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>user-soap-service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
И это мой контекст приложения:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<import resource="classpath:user-service.xml"/>
<bean id="userService" class="com.myorg.service.user.services.UserServiceBean"/>
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
<bean id="userEndpoint" class="com.myorg.api.endpoints.UserMarshallingEndpoint"/>
<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
<property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
</bean>
<bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocation" value="classpath:mapping.xml"/>
</bean>
<bean id="user" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
<property name="schema">
<bean class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="/WEB-INF/user.xsd"/>
</bean>
</property>
<property name="portTypeName" value="User"/>
<property name="locationUri" value="http://localhost:8080/user-soap-service"/>
</bean>
</beans>
Все развертывается отлично (нет ошибок/предупреждений), и если я сравню WSDL, который был запущен, когда он был развернут в Tomcat, и то, что похоже на его развертывание в Glassfish, они идентичны. Есть ли у кого-нибудь мысли о том, что может произойти?
ОБНОВЛЕНИЕ Это действительно неожиданно, но он отлично работает с хорошим старомодным завитом (я ранее тестировал SoapUI). Теперь я собираюсь сосредоточить свое исследование на том, как SoapUI создает свой вызов против того, что я делаю с завитом.
После некоторых экспериментов ключевым моментом здесь является свойство locationUri моего определения Spring wsdl.
При развертывании в Tomcat (7.0.54 - это версия, которую я использую в настоящее время) приложение, похоже, не заботится о одном бите, если вы отправляете запросы (через SoapUI или curl) на localhost:8080/user-soap-service
или localhost:8080/user-soap-service/
- свойство "locationUri", по-видимому, не имеет значения в этом смысле (т.е. я получаю то же самое поведение, независимо от того, поставил ли я трейлинг или нет).
Когда вы развернулись в Glassfish (я нахожусь в версии 4), я получаю совершенно разные виды поведения. Независимо от того, использовал ли я трейлинг/в моей конфигурации или нет, запрос с помощью curl с использованием localhost:8080/user-soap-service
даст мне 303. Выполнение запроса через SoapUI против этого же URL-адреса даст мне 405! Добавление косой черты - то есть localhost:8080/user-soap-service/
- дает мне успешный вызов, используя либо curl, либо SoapUI.
В принципе, до этого момента мое тестирование показало бы, что свойство "locationUri" не работает на корточках - я получаю одинаковое поведение независимо от того, использовал ли я трейлинг/в конце этого URL-адреса или нет. Однако имеет большое значение то, как SoapUI создает ваши запросы по умолчанию, поскольку он создает URL-адрес для отправки запросов на основе WSDL, который вы ему предоставляете, то есть:
<wsdl:service name="UserService">
<wsdl:port binding="tns:UserSoap11" name="UserSoap11">
<soap:address location="http://localhost:8080/user-soap-service/"/>
</wsdl:port>
</wsdl:service>
Мораль истории, которую я отнимаю от этого, заключается в том, чтобы всегда использовать трейлинг-косую черту определения свойства "locationUri" в Spring WSDL, потому что, в зависимости от вашего выбранного контейнера и инструмента тестирования, это может иметь большое значение в том, ваши тесты проходят или нет.
Кроме того, не уменьшайте силу хорошего старого завитка, чтобы раскрыть что-то очевидное, что вы не замечаете!
Это также может произойти, если вы отправляете свой запрос с помощью http, пока разрешено только https
/service
а не абсолютный, как вы описали.