从遗留的jax-ws客户端代码生成wsdl

时间:2015-10-13 00:30:39

标签: wsdl jax-ws

只能使用JAX-WS客户端代码生成WSDL吗?

我有一个没有wsdl的遗留客户端代码,只是远程wsdl uri,我需要为该客户端代码创建mockservices,我需要WSDL来创建这个模拟。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

为了创建模拟/存根服务提供者,我相信如果可以,最好下载原始的WSDL。从客户端生成的代码生成WSDL的风险是生成的WSDL与原始代码完全匹配的明确可能性,这会破坏模拟或存根的目的。

但是,这是我用于从生成的JAX-WS客户端生成WSDL的步骤。我确实需要手动编写一个实现类。

原始WSDL:http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL

  1. 生成JAX-WS客户端: wsimport -extension -keep http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL
  2. 这将创建示例JAX-WS客户端,其中包括生成的服务端点接口(SEI):com.cdyne.ws.weatherws.WeatherSoap

    1. Oddly enough,我们需要一个实现类来运行wsgen来生成WSDL。我手动创建了一个实现类,声明它实现了SEI,然后从接口定义中复制了所有方法,并为每个方法提供了return null;实现。
    2. package com.cdyne.ws.weatherws;
      
      import javax.jws.WebMethod;
      import javax.jws.WebParam;
      import javax.jws.WebResult;
      import javax.jws.WebService;
      import javax.xml.bind.annotation.XmlSeeAlso;
      import javax.xml.ws.RequestWrapper;
      import javax.xml.ws.ResponseWrapper;
      
      @WebService(name = "WeatherSoap", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
      public class WeatherSoapStubImpl implements WeatherSoap {
      
          /**
           * Gets Information for each WeatherID
           * 
           * @return
           *     returns com.cdyne.ws.weatherws.ArrayOfWeatherDescription
           */
          @WebMethod(operationName = "GetWeatherInformation", action = "http://ws.cdyne.com/WeatherWS/GetWeatherInformation")
          @WebResult(name = "GetWeatherInformationResult", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
          @RequestWrapper(localName = "GetWeatherInformation", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "com.cdyne.ws.weatherws.GetWeatherInformation")
          @ResponseWrapper(localName = "GetWeatherInformationResponse", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "com.cdyne.ws.weatherws.GetWeatherInformationResponse")
          public ArrayOfWeatherDescription getWeatherInformation() {
              return null;
          }
      
          /**
           * Allows you to get your City Forecast Over the Next 7 Days, which is updated hourly. U.S. Only
           * 
           * @param zip
           * @return
           *     returns com.cdyne.ws.weatherws.ForecastReturn
           */
          @WebMethod(operationName = "GetCityForecastByZIP", action = "http://ws.cdyne.com/WeatherWS/GetCityForecastByZIP")
          @WebResult(name = "GetCityForecastByZIPResult", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
          @RequestWrapper(localName = "GetCityForecastByZIP", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "com.cdyne.ws.weatherws.GetCityForecastByZIP")
          @ResponseWrapper(localName = "GetCityForecastByZIPResponse", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "com.cdyne.ws.weatherws.GetCityForecastByZIPResponse")
          public ForecastReturn getCityForecastByZIP(
              @WebParam(name = "ZIP", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
              String zip) {
                  return null;
              }
      
          /**
           * Allows you to get your City's Weather, which is updated hourly. U.S. Only
           * 
           * @param zip
           * @return
           *     returns com.cdyne.ws.weatherws.WeatherReturn
           */
          @WebMethod(operationName = "GetCityWeatherByZIP", action = "http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP")
          @WebResult(name = "GetCityWeatherByZIPResult", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
          @RequestWrapper(localName = "GetCityWeatherByZIP", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "com.cdyne.ws.weatherws.GetCityWeatherByZIP")
          @ResponseWrapper(localName = "GetCityWeatherByZIPResponse", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "com.cdyne.ws.weatherws.GetCityWeatherByZIPResponse")
          public WeatherReturn getCityWeatherByZIP(
              @WebParam(name = "ZIP", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
              String zip) {
                  return null;
              }
      }
      
      1. 编译存根实现类。 javac com/cdyne/ws/weatherws/WeatherSoapStubImpl.java

      2. 生成WSDL。这是命令行开关可以用来尽可能接近原始位置的地方。 wsgen -keep -cp . com.cdyne.ws.weatherws.WeatherSoapStubImpl -wsdl:Xsoap1.2 -extension -inlineSchemas (在当前目录中创建WSDL):

      3. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#8c29a9a53251ff741fca1664a8221dc876b2eac8. -->
        <definitions targetNamespace="http://ws.cdyne.com/WeatherWS/" name="WeatherSoapStubImplService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:tns="http://ws.cdyne.com/WeatherWS/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">
          <types>
            <xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://ws.cdyne.com/WeatherWS/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        
              <xs:element name="GetCityForecastByZIP" type="tns:GetCityForecastByZIP"/>
        
              <xs:element name="GetCityForecastByZIPResponse" type="tns:GetCityForecastByZIPResponse"/>
        
              <xs:element name="GetCityWeatherByZIP" type="tns:GetCityWeatherByZIP"/>
        
              <xs:element name="GetCityWeatherByZIPResponse" type="tns:GetCityWeatherByZIPResponse"/>
        
              <xs:element name="GetWeatherInformation" type="tns:GetWeatherInformation"/>
        
              <xs:element name="GetWeatherInformationResponse" type="tns:GetWeatherInformationResponse"/>
        
              <xs:complexType name="GetWeatherInformation">
                <xs:sequence/>
              </xs:complexType>
        
              <xs:complexType name="GetWeatherInformationResponse">
                <xs:sequence>
                  <xs:element name="GetWeatherInformationResult" type="tns:ArrayOfWeatherDescription" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="ArrayOfWeatherDescription">
                <xs:sequence>
                  <xs:element name="WeatherDescription" type="tns:WeatherDescription" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="WeatherDescription">
                <xs:sequence>
                  <xs:element name="WeatherID" type="xs:short"/>
                  <xs:element name="Description" type="xs:string" minOccurs="0"/>
                  <xs:element name="PictureURL" type="xs:string" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="GetCityWeatherByZIP">
                <xs:sequence>
                  <xs:element name="ZIP" type="xs:string" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="GetCityWeatherByZIPResponse">
                <xs:sequence>
                  <xs:element name="GetCityWeatherByZIPResult" type="tns:WeatherReturn" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="WeatherReturn">
                <xs:sequence>
                  <xs:element name="Success" type="xs:boolean"/>
                  <xs:element name="ResponseText" type="xs:string" minOccurs="0"/>
                  <xs:element name="State" type="xs:string" minOccurs="0"/>
                  <xs:element name="City" type="xs:string" minOccurs="0"/>
                  <xs:element name="WeatherStationCity" type="xs:string" minOccurs="0"/>
                  <xs:element name="WeatherID" type="xs:short"/>
                  <xs:element name="Description" type="xs:string" minOccurs="0"/>
                  <xs:element name="Temperature" type="xs:string" minOccurs="0"/>
                  <xs:element name="RelativeHumidity" type="xs:string" minOccurs="0"/>
                  <xs:element name="Wind" type="xs:string" minOccurs="0"/>
                  <xs:element name="Pressure" type="xs:string" minOccurs="0"/>
                  <xs:element name="Visibility" type="xs:string" minOccurs="0"/>
                  <xs:element name="WindChill" type="xs:string" minOccurs="0"/>
                  <xs:element name="Remarks" type="xs:string" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="GetCityForecastByZIP">
                <xs:sequence>
                  <xs:element name="ZIP" type="xs:string" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="GetCityForecastByZIPResponse">
                <xs:sequence>
                  <xs:element name="GetCityForecastByZIPResult" type="tns:ForecastReturn" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="ForecastReturn">
                <xs:sequence>
                  <xs:element name="Success" type="xs:boolean"/>
                  <xs:element name="ResponseText" type="xs:string" minOccurs="0"/>
                  <xs:element name="State" type="xs:string" minOccurs="0"/>
                  <xs:element name="City" type="xs:string" minOccurs="0"/>
                  <xs:element name="WeatherStationCity" type="xs:string" minOccurs="0"/>
                  <xs:element name="ForecastResult" type="tns:ArrayOfForecast" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="ArrayOfForecast">
                <xs:sequence>
                  <xs:element name="Forecast" type="tns:Forecast" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="Forecast">
                <xs:sequence>
                  <xs:element name="Date" type="xs:dateTime"/>
                  <xs:element name="WeatherID" type="xs:short"/>
                  <xs:element name="Desciption" type="xs:string" minOccurs="0"/>
                  <xs:element name="Temperatures" type="tns:temp"/>
                  <xs:element name="ProbabilityOfPrecipiation" type="tns:POP"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="temp">
                <xs:sequence>
                  <xs:element name="MorningLow" type="xs:string" minOccurs="0"/>
                  <xs:element name="DaytimeHigh" type="xs:string" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        
              <xs:complexType name="POP">
                <xs:sequence>
                  <xs:element name="Nighttime" type="xs:string" minOccurs="0"/>
                  <xs:element name="Daytime" type="xs:string" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
        </xs:schema>
          </types>
          <message name="GetWeatherInformation">
            <part name="parameters" element="tns:GetWeatherInformation"/>
          </message>
          <message name="GetWeatherInformationResponse">
            <part name="parameters" element="tns:GetWeatherInformationResponse"/>
          </message>
          <message name="GetCityForecastByZIP">
            <part name="parameters" element="tns:GetCityForecastByZIP"/>
          </message>
          <message name="GetCityForecastByZIPResponse">
            <part name="parameters" element="tns:GetCityForecastByZIPResponse"/>
          </message>
          <message name="GetCityWeatherByZIP">
            <part name="parameters" element="tns:GetCityWeatherByZIP"/>
          </message>
          <message name="GetCityWeatherByZIPResponse">
            <part name="parameters" element="tns:GetCityWeatherByZIPResponse"/>
          </message>
          <portType name="WeatherSoap">
            <operation name="GetWeatherInformation">
              <input wsam:Action="http://ws.cdyne.com/WeatherWS/GetWeatherInformation" message="tns:GetWeatherInformation"/>
              <output wsam:Action="http://ws.cdyne.com/WeatherWS/WeatherSoap/GetWeatherInformationResponse" message="tns:GetWeatherInformationResponse"/>
            </operation>
            <operation name="GetCityForecastByZIP">
              <input wsam:Action="http://ws.cdyne.com/WeatherWS/GetCityForecastByZIP" message="tns:GetCityForecastByZIP"/>
              <output wsam:Action="http://ws.cdyne.com/WeatherWS/WeatherSoap/GetCityForecastByZIPResponse" message="tns:GetCityForecastByZIPResponse"/>
            </operation>
            <operation name="GetCityWeatherByZIP">
              <input wsam:Action="http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP" message="tns:GetCityWeatherByZIP"/>
              <output wsam:Action="http://ws.cdyne.com/WeatherWS/WeatherSoap/GetCityWeatherByZIPResponse" message="tns:GetCityWeatherByZIPResponse"/>
            </operation>
          </portType>
          <binding name="WeatherSoapPortBinding" type="tns:WeatherSoap">
            <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
            <operation name="GetWeatherInformation">
              <soap12:operation soapAction="http://ws.cdyne.com/WeatherWS/GetWeatherInformation"/>
              <input>
                <soap12:body use="literal"/>
              </input>
              <output>
                <soap12:body use="literal"/>
              </output>
            </operation>
            <operation name="GetCityForecastByZIP">
              <soap12:operation soapAction="http://ws.cdyne.com/WeatherWS/GetCityForecastByZIP"/>
              <input>
                <soap12:body use="literal"/>
              </input>
              <output>
                <soap12:body use="literal"/>
              </output>
            </operation>
            <operation name="GetCityWeatherByZIP">
              <soap12:operation soapAction="http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP"/>
              <input>
                <soap12:body use="literal"/>
              </input>
              <output>
                <soap12:body use="literal"/>
              </output>
            </operation>
          </binding>
          <service name="WeatherSoapStubImplService">
            <port name="WeatherSoapPort" binding="tns:WeatherSoapPortBinding">
              <soap12:address location="REPLACE_WITH_ACTUAL_URL"/>
            </port>
          </service>
        </definitions>
        
        1. 使用SOAPUI
        2. 等工具创建存根或模拟服务

          通过这种方法和简单的服务接口,我能够成功地将SOAP消息与客户端一起发送到使用生成的WSDL创建的SOAPUI中创建的模拟服务提供者。