简体   繁体   English

WSDL 操作中的 soapAction 属性为空

[英]soapAction attribute in WSDL operation is empty

There is a web service with the following WSDL:有一个具有以下 WSDL 的 Web 服务:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://fer2.klab/notify" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://fer2.klab/notify" targetNamespace="http://fer2.klab/notify">
  <wsdl:types>
    <xs:schema xmlns:er="http://fer2.klab/notify" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://fer2.klab/notify">
    <xs:element name="ServiceRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="1" name="HL7message" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="ServiceResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="1" name="response" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
  </wsdl:types>
  <wsdl:message name="ServiceResponse">
    <wsdl:part element="tns:ServiceResponse" name="ServiceResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="ServiceRequest">
    <wsdl:part element="tns:ServiceRequest" name="ServiceRequest">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="NotifyPort">
    <wsdl:operation name="Service">
      <wsdl:input message="tns:ServiceRequest" name="ServiceRequest">
    </wsdl:input>
      <wsdl:output message="tns:ServiceResponse" name="ServiceResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="NotifyPortSoap11" type="tns:NotifyPort">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="Service">
      <soap:operation soapAction=""/>
      <wsdl:input name="ServiceRequest">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="ServiceResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="NotifyPortService">
    <wsdl:port binding="tns:NotifyPortSoap11" name="NotifyPortSoap11">
      <soap:address location="http://192.168.1.101:8080/fer2-0.0.1/ws"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

There is an endpoint:有一个端点:

@Endpoint
public class NotifyEndPoint {

    private static final String NAMESPACE_URL = "http://fer2.klab/notify";

    @Autowired
    MainController mainController;

    @PayloadRoot(namespace = NAMESPACE_URL, localPart = "ServiceRequest")
    @ResponsePayload
    public ServiceResponse send(@RequestPayload ServiceRequest hlMessage){
        System.out.println("notify method");
        Object resp = mainController.notify(null, "", hlMessage.getHL7Message());
        ServiceResponse sr = new ServiceResponse();
        if (resp != null){
            sr.setResponse(resp.toString());
        }
        else{
            sr.setResponse("null");
        }

        return sr;
    }
}

dispatcher-servlet.xml:调度员-servlet.xml:

<bean id="notify" name="notify" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
    <!--<property name="createSoap12Binding" value="true" />-->
    <property name="portTypeName" value="NotifyPort" />
    <property name="locationUri" value="/ws" />
    <property name="schema">
        <bean class="org.springframework.xml.xsd.SimpleXsdSchema">
            <property name="xsd" value="notify.xsd" />
        </bean>
    </property>
    <property name="targetNamespace" value="http://fer2.klab/notify" />
    <!--<property name="soapActions">-->
        <!--<props>-->
            <!--<prop key="ServiceRequest">http://fer2.klab/notify/ServiceRequest"</prop>-->
        <!--</props>-->
    <!--</property>-->
</bean>

application-config.xml:应用程序-config.xml:

<bean class="klab.backend.utils.MainConfig" id="mainConfig">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="locations">
        <list>
            <value>/WEB-INF/main.properties</value>
            <value>/WEB-INF/build.properties</value>
        </list>
    </property>
</bean>

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="writeAcceptCharset" value="true"/>
        </bean>
        <bean class="klab.backend.utils.json.JacksonView2HttpMessageConverter">

            <property name="objectMapper">
                <bean class="klab.backend.utils.json.KJsonMapper">
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

<context:component-scan base-package="klab.fer2"/>

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
    <property name="validator" ref="validator"/>
</bean>

<bean class="klab.backend.controller.base.DefaultController"/>

<bean name="CorsFilter" class="klab.backend.filter.CorsFilter"/>

Why does Service operation in generated WSDL has empty attribute soapAction ?为什么生成的 WSDL 中的Service操作具有空属性soapAction

SOAP-request to URL http://192.168.1.101:8080/fer2-0.0.1/ws with following content:对 URL http://192.168.1.101:8080/fer2-0.0.1/ws的 SOAP 请求,内容如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:not="http://fer2.klab/notify">
   <soapenv:Header/>
   <soapenv:Body>
      <not:ServiceRequest>
         <not:HL7message>hdfghdfghdfgh</not:HL7message>
      </not:ServiceRequest>
   </soapenv:Body>
</soapenv:Envelope>

results in the following error logged:导致记录以下错误:

 org.springframework.ws.server.EndpointNotFound- No endpoint mapping found for [SaajSoapMessage {http://fer2.klab/notify}ServiceRequest]

The soapAction attribute of the soap:operation element is the value that will be included in the HTTP request message, as in: soap:operation元素的soapAction属性是将包含在 HTTP 请求消息中的值,如下所示:

POST /StockQuote HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "http://electrocommerce.org/abc#MyMessage"

As stated in the specification this value only indicates the intent of which operation will be called and it's not normally used by the web services frameworks when creating the stubs.规范中所述,此值仅指示将调用哪个操作的意图,并且在创建存根时 Web 服务框架通常不会使用它。

A common pattern is to set it to empty string as in <soap:operation soapAction="" which means that the operation that the request is referring to is indicated inside the http request's payload.一种常见的模式是将其设置为空字符串,如<soap:operation soapAction="" ,这意味着请求所指的操作在 http 请求的有效负载中指示。 So your wsdl looks fine in that regard.所以你的 wsdl 在这方面看起来很好。

In Spring though, you can annotate a method with @SoapAction and that method will be mapped using the soapAction header.但是在Spring中,您可以使用@SoapAction注释方法,并且该方法将使用 soapAction 标头进行映射。 But you are using @PayloadRoot on your method, so it will be mapped using the local name 'ServiceRequest', therefore the value of the soapAction will be "" and it will not be used.但是您在方法上使用@PayloadRoot ,因此它将使用本地名称“ServiceRequest”进行映射,因此 soapAction 的值将为""并且不会被使用。

Problem was finally solved.问题终于解决了。

WSDL was autogenerated and made static. WSDL 是自动生成的并且是静态的。

Endpoint was changed like this (the main point here is @Action annotation):端点是这样改的(这里的重点是@Action注解):

@Endpoint
public class NotifyEndPoint {

    private static final String NAMESPACE_URL = "http://fer2.klab/notify";

    @Autowired
    MainController mainController;

    @PayloadRoot(namespace = NAMESPACE_URL, localPart = "ServiceRequest")
    @Action("http://fer2.klab/notify/ServiceRequest")
//    @ResponsePayload
    public void send(@RequestPayload ServiceRequest hlMessage) {
        System.out.println("notify method");
        mainController.notify(null, "", hlMessage.getHL7Message());
    }

}

dispatcher-servlet.xml changed to this: dispatcher-servlet.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:context="http://www.springframework.org/schema/context"
       xmlns:sws="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <sws:annotation-driven />

    <bean id="notify" name="notify" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
        <property name="wsdl" value="notify.wsdl" />
    </bean>

    <context:component-scan base-package="klab.fer2"/>

</beans>

For me it worked only (spring-boot app):对我来说它只有效(spring-boot 应用程序):

Resolve empty soapAction 解决空肥皂动作

wsdl11Definition.setSoapActions(soapActions); wsdl11Definition.setSoapActions(soapActions);

public class WebServiceConfig extends WsConfigurerAdapter {

@Bean(name = "someService")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema schema) {
    DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    ....

    Properties soapActions = new Properties();
    for (Method method : endpointController.class.getMethods() ) {
        soapActions.setProperty(method.getName(), Const.NAMESPACE_URI + "/#" + method.getName());
    }
    wsdl11Definition.setSoapActions(soapActions);

    return wsdl11Definition;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM