找不到SaajSoapMessage的端点映射

时间:2014-01-21 00:16:15

标签: spring soap

我一直在尝试让端点映射为我的Web服务工作时遇到问题。我正在使用Tomcat来托管我的Web服务,我使用soapUI向它发送测试消息。

Tomcat日志中的以下消息显示了端点映射bean的创建:

6458 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping  - Mapped key [{http://endpoint.ws.example.com}pushAbcToXyzOperation] onto endpoint [com.abc.xc.model.PushAbcToXyzRequest@131ebb3[...]]

但是,端点映射bean必须不正确,因为我收到以下“未找到端点映射”消息:

6739 [http-apr-8080-exec-6] WARN  org.springframework.ws.server.EndpointNotFound  - No endpoint mapping found for [SaajSoapMessage {http://endpoint.ws.example.com}pushAbcToXyzOperation]

这是web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <display-name>abc2xyzWS</display-name>

    <servlet>
        <servlet-name>spring-ws</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring-ws-context.xml</param-value>
    </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-ws</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

这是spring-ws-context.xml

<?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:sws="http://www.springframework.org/schema/web-services"
       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-3.0.xsd
        http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd">

    <sws:annotation-driven/>
    <context:annotation-config />

    <import resource="classpath:/xyz-endpoint-context.xml" />

    <!--==========================================================
    *
    *  Spring Web Service Configuration
    *
    =============================================================-->

    <bean name="loadPayload" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
        <description>
            Detects @PayloadRoot annotations on @Endpoint bean methods.
        </description>

        <property name="interceptors">
            <list>
                <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
                <bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
                    <property name="schema" value="classpath:/AbcAPI.xsd"/>
                    <property name="validateRequest" value="true"/>
                    <property name="validateResponse" value="true"/>
                </bean>
            </list>
        </property>

        <property name="order" value="1"/>
    </bean>

    <bean id="pushService" class="com.abc.xc.model.PushAbcToXyzRequest"/>

    <bean id="endpointMapping" class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
       <property name="mappings">
          <props>
              <prop key="{http://endpoint.ws.example.com}pushAbcToXyzOperation">pushService</prop>
          </props>
       </property>

    </bean>

</beans>

这是xyz-endpoint-context.xml

<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-3.0.xsd">

    <import resource="classpath:/applicationContext.xml" />
    <context:component-scan base-package="com.abc.ws.endpoint"/>
</beans>

这是applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       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-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!--===========================================================================
     *
     *  opis2pips service module configuration.
     *
     =============================================================================-->
     <context:property-placeholder location="classpath:/applicationContext.properties"/>
     <context:component-scan base-package="com.abc.xc.service"/>

     <bean id="serviceURL" class="java.lang.String">
         <constructor-arg><value>${serviceURL}</value></constructor-arg>
     </bean>
     ...
     <bean id="emailerrormessage" class="java.lang.String">
        <constructor-arg><value>${emailerrormessage}</value></constructor-arg>
     </bean> 

</beans>

这是端点

package com.abc.ws.endpoint.endpoint;

import com.abc.xc.model.WSstatusType;
import com.abc.xc.model.PushAbcToXyzRequest;
import com.abc.xc.model.QueryXyzRequest;
import com.abc.xc.model.XyzResponse;
import com.abc.xc.service.XyzClient;
import com.abc.xc.service.WSemailService;
import com.abc.xc.service.AbcToXyzTranslationService;
import com.abc.xc.exception.WSexception;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;

import contracts.xyz.GetTicketResponse;
import contracts.xyz.PostTicketResponse;
import contracts.xyz.Ticket;
import contracts.xyz.TicketMessageProcessingResult;

@Endpoint
public class XyzWebServiceController {
    @Autowired
    private XyzClient XyzClientservice;
    @Autowired
    private AbcToXyzTranslationService translationservice;
    @Autowired
    WSemailService mailservice;

    protected static final String NAMESPACE_URI = "http://www.example.com/schema";

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "PushAbcToXyzRequest")

    @ResponsePayload
    public XyzResponse PushAbcToXyzOperation(@RequestPayload PushAbcToXyzRequest PushAbcToXyzRequest){

        XyzResponse XyzResponse = null;
        Ticket ticket = null;
        try {
            ticket = translationservice.abcInputToXyzTicket(PushAbcToXyzRequest);
            PostTicketResponse response = XyzClientservice.postTicket(ticket);
            Long transactionid = response.getInteractionId();

            if(transactionid != null){
                GetTicketResponse gtresponse = XyzClientservice.getTicket();
                Ticket gtresponseTicket = gtresponse.getTicket().getValue();
                XyzResponse =  translationservice.XyzTicketToXyzResponse(gtresponseTicket);
            }

            XyzResponse.setWSstatus(WSstatusType.SUCCESS);
            mailservice.sendEmail(true, PushAbcToXyzRequest, transactionid);
...

这是SOAP请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:end="http://endpoint.ws.example.com" xmlns:mod="http://model.xc.example.com">
   <soapenv:Header/>
   <soapenv:Body>
      <end:pushAbcToXyzOperation>
         <end:pushAbcToXyzRequest>
            ...
         </end:pushAbcToXyzRequest>
      </end:pushAbcToXyzOperation>
   </soapenv:Body>
</soapenv:Envelope>

以下是Tomcat日志的一部分,从创建端点映射bean到通过“找不到端点映射”消息:

6349 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Finished creating instance of bean 'loadPayload'
6349 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Creating shared instance of singleton bean 'pushService'
6349 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Creating instance of bean 'pushService'
6365 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Eagerly caching bean 'pushService' to allow for resolving potential circular references
6427 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Finished creating instance of bean 'pushService'
6427 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Creating shared instance of singleton bean 'endpointMapping'
6427 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Creating instance of bean 'endpointMapping'
6427 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Eagerly caching bean 'endpointMapping' to allow for resolving potential circular references
6443 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'pushService'
6458 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping  - Mapped key [{http://endpoint.ws.example.com}pushAbcToXyzOperation] onto endpoint [com.abc.xc.model.PushAbcToXyzRequest@131ebb3[requestID=<null>, ...]]
6458 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Finished creating instance of bean 'endpointMapping'
6458 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0'
6474 [http-apr-8080-exec-6] DEBUG org.springframework.web.context.support.XmlWebApplicationContext  - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@13a0067]
6474 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'lifecycleProcessor'
6505 [http-apr-8080-exec-6] INFO  org.springframework.ws.soap.saaj.SaajSoapMessageFactory  - Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
6505 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.saaj.SaajSoapMessageFactory  - Using MessageFactory class [com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl]
6505 [http-apr-8080-exec-6] DEBUG org.springframework.ws.transport.http.MessageDispatcherServlet  - No WebServiceMessageFactory found in servlet 'spring-ws': using default
6505 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter#0'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver#0'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver#0'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping#0'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping#0'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping#0'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'loadPayload'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'endpointMapping'
6521 [http-apr-8080-exec-6] DEBUG org.springframework.ws.transport.http.MessageDispatcherServlet  - No MessageDispatcher found in servlet 'spring-ws': using default
6521 [http-apr-8080-exec-6] DEBUG org.springframework.ws.transport.http.MessageDispatcherServlet  - Published WebApplicationContext of servlet 'spring-ws' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-ws]
6521 [http-apr-8080-exec-6] INFO  org.springframework.ws.transport.http.MessageDispatcherServlet  - FrameworkServlet 'spring-ws': initialization completed in 6053 ms
6521 [http-apr-8080-exec-6] DEBUG org.springframework.ws.transport.http.MessageDispatcherServlet  - Servlet 'spring-ws' configured successfully
6583 [http-apr-8080-exec-6] DEBUG org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter  - Accepting incoming [org.springframework.ws.transport.http.HttpServletConnection@7ac6c] at [http://localhost:8080/abc2xyzWS/services/XyzWebServiceController]
6677 [http-apr-8080-exec-6] DEBUG org.springframework.ws.server.MessageTracing.received  - Received request [SaajSoapMessage {http://endpoint.ws.example.com}pushAbcToXyzOperation]
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping  - Looking up endpoint for [{http://endpoint.ws.example.com}pushAbcToXyzOperation]
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher  - Endpoint mapping [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping@14481bb] has no mapping for request
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping  - Looking up endpoint for []
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher  - Endpoint mapping [org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping@a14fed] has no mapping for request
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping  - Looking up endpoint for [{http://endpoint.ws.example.com}pushAbcToXyzOperation]
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher  - Endpoint mapping [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping@868c6d] has no mapping for request
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher  - Endpoint mapping [org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping@45484a] has no mapping for request
6723 [http-apr-8080-exec-6] DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher  - Endpoint mapping [org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping@8d00c6] has no mapping for request
6739 [http-apr-8080-exec-6] WARN  org.springframework.ws.server.EndpointNotFound  - No endpoint mapping found for [SaajSoapMessage {http://endpoint.ws.example.com}pushAbcToXyzOperation]

如果您需要查看任何其他信息,请与我们联系,并提前感谢您解决此问题的任何帮助。

6 个答案:

答案 0 :(得分:2)

我们遇到了类似的问题,在我们的案例中,EndPoint未包含在弹簧配置的组件扫描指令中。

在您指示使用的配置中:

<context:component-scan base-package="com.abc.ws.endpoint"/>

但您的终端位于下一个包中:

package com.abc.ws.endpoint.endpoint;

所以你必须改变组件扫描标签,例如:

<context:component-scan base-package="com.abc.ws.endpoint.endpoint"/>

或者将端点重构为另一个包。

答案 1 :(得分:0)

NAMESPACE_URI值是否应该与spring-ws-context.xml中wsdl和xml endpointMapping中指定的命名空间相同? NAMESPACE_URI中指定的命名空间不包含“.ws”,它包含在wsdl命名空间和endpointMapping配置中。

为了帮助解决此问题并将来作为回归测试,您可能希望编写一个“端点集成测试”,您可以从Eclipse运行并作为构建过程的一部分(http://docs.spring.io/spring-ws/site/reference/html/server.html#d5e1526)。

答案 2 :(得分:0)

我认为你的问题是你有多个ApplicationContexts(多个包含bean定义的xml-s),而 PayloadRootAnnotationMethodEndpointMapping 默认只在自己的ApplicationContext中查找端点(在它自己的xml中)。要强制检测其他xml-s中的端点,您必须将 PayloadRootAnnotationMethodEndpointMapping detectEndpointsInAncestorContexts 属性设置为 true

答案 3 :(得分:0)

在我的例子中,我只是添加了带有端点类和实现类的上下文标记包,如:

 <context:component-scan base-package="com.abc.ws.services ,com.abc.ws.endpoint"/>

答案 4 :(得分:0)

我关注Spring's guide on creating a SOAP web service using Springboot并得到了同样的错误。我不确定是什么原因造成的,但我发现当我在集成测试中尝试使用WebServiceTemplate这样的请求时,我得到了404,即使在我的测试执行期间服务器已启动并且WSDL可用。这就是我在没有工作时所做的事情:

    final String request = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
            "\t\t\t\t  xmlns:gs=\"http://spring.io/guides/gs-producing-web-service\">\n" +
            "   <soapenv:Header/>\n" +
            "   <soapenv:Body>\n" +
            "      <gs:getCountryRequest>\n" +
            "         <gs:name>Spain</gs:name>\n" +
            "      </gs:getCountryRequest>\n" +
            "   </soapenv:Body>\n" +
            "</soapenv:Envelope>";

    StreamSource source = new StreamSource(new StringReader(request));
    StreamResult result = new StreamResult(System.out);

    webServiceTemplate.sendSourceAndReceiveToResult("http://localhost:8080/ws", source, result);

当我改变它以使用marshaller而不是像这样的原始请求字符串时:

        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("io.spring.guides.gs_producing_web_service");
    marshaller.setSchema(new ClassPathResource("countries.xsd"));
    webServiceTemplate.setMarshaller(marshaller);
    webServiceTemplate.setUnmarshaller(marshaller);

    GetCountryRequest getCountryRequest = new GetCountryRequest();
    getCountryRequest.setName("Spain");
    GetCountryResponse getCountryResponse = (GetCountryResponse) webServiceTemplate.marshalSendAndReceive("http://localhost:" + serverPort + "/ws", getCountryRequest);

    assertThat(getCountryResponse.getCountry().getName()).isEqualTo("Spain");
    assertThat(getCountryResponse.getCountry().getCapital()).isEqualTo("Madrid");
    assertThat(getCountryResponse.getCountry().getCurrency()).isEqualTo(Currency.EUR);
    assertThat(getCountryResponse.getCountry().getPopulation()).isEqualTo(46704314);

我实际使用生成的WSDL类,然后相同的请求成功。我有一种感觉,原始的原始请求字符串是不兼容的,即使我可以通过curl请求使用完全相同的字符串到我的SOAP端点并且可以工作(就像它告诉你在指南中做的那样)。

答案 5 :(得分:0)

将班级XyzWebServiceController重命名为XyzWebServiceControllerEndpoint