只能使用JAX-WS客户端代码生成WSDL吗?
我有一个没有wsdl的遗留客户端代码,只是远程wsdl uri,我需要为该客户端代码创建mockservices,我需要WSDL来创建这个模拟。
有什么想法吗?
答案 0 :(得分:1)
为了创建模拟/存根服务提供者,我相信如果可以,最好下载原始的WSDL。从客户端生成的代码生成WSDL的风险是生成的WSDL与原始代码完全匹配的明确可能性,这会破坏模拟或存根的目的。
但是,这是我用于从生成的JAX-WS客户端生成WSDL的步骤。我确实需要手动编写一个实现类。
原始WSDL:http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL
wsimport -extension -keep http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL
这将创建示例JAX-WS客户端,其中包括生成的服务端点接口(SEI):com.cdyne.ws.weatherws.WeatherSoap
wsgen
来生成WSDL。我手动创建了一个实现类,声明它实现了SEI,然后从接口定义中复制了所有方法,并为每个方法提供了return null;
实现。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;
}
}
编译存根实现类。
javac com/cdyne/ws/weatherws/WeatherSoapStubImpl.java
生成WSDL。这是命令行开关可以用来尽可能接近原始位置的地方。
wsgen -keep -cp . com.cdyne.ws.weatherws.WeatherSoapStubImpl -wsdl:Xsoap1.2 -extension -inlineSchemas
(在当前目录中创建WSDL):
<?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>
通过这种方法和简单的服务接口,我能够成功地将SOAP消息与客户端一起发送到使用生成的WSDL创建的SOAPUI中创建的模拟服务提供者。