Служба SOAP на основе Spring-WS возвращает значение 405 при развертывании в Glassfish

#java #web-services #soap #glassfish #spring-ws

#java — язык #веб-сервисы #мыло #стеклянная рыба #весна-ws #java #soap #glassfish #spring-ws

Вопрос:

Мне это кажется немного странным — у меня есть очень простой SOAP-сервис, встроенный в Spring-WS, который развертывается и отлично работает внутри контейнера Tomcat 7. В последнее время я экспериментировал с Glassfish 4 и пытался заставить этот SOAP-сервис работать, но каждый раз, когда я пытаюсь протестировать вызов через SoapUI, получаю сообщение «Метод 405 не разрешен».

Есть ли у кого-нибудь какие-либо советы о том, что может вызвать это? Это точно такая же война, развернутая в обоих контейнерах — единственное изменение, которое я внес, — это настройка поиска JNDI в моем источнике данных на моем сервисном уровне, все остальное идентично.

Действительно странно то, что при развертывании в Glassfish она будет обслуживать WSDL (т. Е. localhost:8080/user-soap-service/user.wsdl ), поэтому я знаю, что приложение развернуто / прослушивает этот URL-адрес — кажется, оно просто отказывается пропускать какие-либо сообщения.

Это мой 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, они идентичны. У кого-нибудь есть какие-либо мысли о том, что может происходить?

ОБНОВЛЕНИЕ Это действительно неожиданно, но оно отлично работает со старым добрым curl (ранее я тестировал с SoapUI). Теперь я собираюсь сосредоточить свое исследование на том, как SoapUI строит свой вызов в сравнении с тем, что я делаю с curl.

Ответ №1:

После некоторых экспериментов ключевым моментом здесь, по-видимому, является свойство «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» не выполняет squat — я получаю одинаковое поведение независимо от того, использовал ли я завершающий / в конце 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>
  

Мораль истории, которую я удаляю из этого, заключается в том, чтобы всегда использовать завершающую косую черту в свойстве компонента определения Spring WSDL «locationUri», потому что, в зависимости от выбранного вами контейнера и инструмента тестирования, это может сильно повлиять на то, пройдут ли ваши тесты или нет.

Кроме того, не стоит сбрасывать со счетов способность старого доброго curl раскрыть что-то очевидное, что вы упускаете из виду!

Комментарии:

1. Рад, что ты сам это понял! С этим я столкнулся и с другими проблемами, особенно когда вы начинаете развертывать одну и ту же войну в разных средах. Я решил эту проблему, используя относительный URL типа /service вместо абсолютного, как вы описываете.

Ответ №2:

Это также может произойти, если вы отправляете запрос с использованием http, в то время как разрешен только https