Advanced Java Services | WebServices 2 |
Das Problem ist für jede Sprache das Gleiche. Es muß eine Verbindung zum Service-Endpoint aufgebaut werden. Dann muß als nächstes die wsdl-Datei ausgelesen werden. Aus dieser Datei muß eine Klasse (oder mehrere) erzeugt werden und davon ein Objekt instanziiert werden. Mit diesem Objekt kann man dann über RMI die Methoden aufrufen. In C# kann man sich die zur wsdl-Datei gehörige Klasse u.a. mit dem Konsoltool wsdl.exe erzeugen lassen.
Man ruft wsdl.exe am besten in einem eigenen Verzeichnis auf. In unserem Fall lautet der Aufruf wsdl http://localhost:8080/WebServiceServlet?wsdl
wsdl.exe erzeugt eine Klasse, die das Service Endpoint Interface in C# realisiert. Hier die Klasse, die dieses Tool in unserem Fall erzeugt.
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:2.0.50727.3643 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using System; using System.ComponentModel; using System.Diagnostics; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; // // This source code was auto-generated by wsdl, Version=2.0.50727.3038. // /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="DayTimeServiceSoapBinding", Namespace="http://timeservice/")] public partial class DayTimeService : System.Web.Services.Protocols.SoapHttpClientProtocol { private System.Threading.SendOrPostCallback getUnixTimeOperationCompleted; private System.Threading.SendOrPostCallback getServerTimeOperationCompleted; /// <remarks/> public DayTimeService() { this.Url = "http://localhost:8080/WebServiceServlet"; } /// <remarks/> public event getUnixTimeCompletedEventHandler getUnixTimeCompleted; /// <remarks/> public event getServerTimeCompletedEventHandler getServerTimeCompleted; /// <remarks/> [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://timeservice/", ResponseNamespace="http://timeservice/", Use=System.Web.Services.Description.SoapBindingUse.Literal)] [return: System.Xml.Serialization.XmlElementAttribute("return")] public long getUnixTime() { object[] results = this.Invoke("getUnixTime", new object[0]); return ((long)(results[0])); } /// <remarks/> public System.IAsyncResult BegingetUnixTime(System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("getUnixTime", new object[0], callback, asyncState); } /// <remarks/> public long EndgetUnixTime(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((long)(results[0])); } /// <remarks/> public void getUnixTimeAsync() { this.getUnixTimeAsync(null); } /// <remarks/> public void getUnixTimeAsync(object userState) { if ((this.getUnixTimeOperationCompleted == null)) { this.getUnixTimeOperationCompleted = new System.Threading.SendOrPostCallback(this.OngetUnixTimeOperationCompleted); } this.InvokeAsync("getUnixTime", new object[0], this.getUnixTimeOperationCompleted, userState); } private void OngetUnixTimeOperationCompleted(object arg) { if ((this.getUnixTimeCompleted != null)) { System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); this.getUnixTimeCompleted(this, new getUnixTimeCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); } } /// <remarks/> [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://timeservice/", ResponseNamespace="http://timeservice/", Use=System.Web.Services.Description.SoapBindingUse.Literal)] [return: System.Xml.Serialization.XmlElementAttribute("return")] public string getServerTime(string arg0) { object[] results = this.Invoke("getServerTime", new object[] { arg0}); return ((string)(results[0])); } /// <remarks/> public System.IAsyncResult BegingetServerTime(string arg0, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("getServerTime", new object[] { arg0}, callback, asyncState); } /// <remarks/> public string EndgetServerTime(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); } /// <remarks/> public void getServerTimeAsync(string arg0) { this.getServerTimeAsync(arg0, null); } /// <remarks/> public void getServerTimeAsync(string arg0, object userState) { if ((this.getServerTimeOperationCompleted == null)) { this.getServerTimeOperationCompleted = new System.Threading.SendOrPostCallback(this.OngetServerTimeOperationCompleted); } this.InvokeAsync("getServerTime", new object[] { arg0}, this.getServerTimeOperationCompleted, userState); } private void OngetServerTimeOperationCompleted(object arg) { if ((this.getServerTimeCompleted != null)) { System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); this.getServerTimeCompleted(this, new getServerTimeCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); } } /// <remarks/> public new void CancelAsync(object userState) { base.CancelAsync(userState); } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void getUnixTimeCompletedEventHandler(object sender, getUnixTimeCompletedEventArgs e); /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class getUnixTimeCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; internal getUnixTimeCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } /// <remarks/> public long Result { get { this.RaiseExceptionIfNecessary(); return ((long)(this.results[0])); } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void getServerTimeCompletedEventHandler(object sender, getServerTimeCompletedEventArgs e); /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class getServerTimeCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; internal getServerTimeCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } /// <remarks/> public string Result { get { this.RaiseExceptionIfNecessary(); return ((string)(this.results[0])); } } }
Damit reduziert sich das Programm auf wenige Zeilen.
class Program { static void Main(string[] args) { DayTimeService dts = new DayTimeService(); string servertime = dts.getServerTime("ge"); long time = dts.getUnixTime(); Console.WriteLine(servertime); Console.WriteLine(time); } }
Will man von Java aus einen WebService ansprechen, den man nicht selbst geschrieben hat, so hat man das gleiche Problem wie oben bei dem C#-Client, man muß den Service ansprechen und die wsdl auslesen und daraus Javaklassen erzeugen. Hierzu gibt es das Konsoltool wsimport.exe.
Der Aufruf hat die Form wsimport -p <packagename> -keep <url-adresse>?wsdl, in unserem Fall also wsimport -p timeservice -keep http://127.0.0.1:5001/timeservice?wsdl. keep bedeutet dabei, daß die erzeugten Javadateien nicht gelöscht werden.
Erzeugt wird das Service Endpoint Interface (DayTimeService) und eine Unterklasse von javax.xml.ws.Service. Mit der letzteren kann man eine Verbindung zum Server aufbauen und die Methoden des SEI aufurfen.
package timeservice; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.xml.ws.Action; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.2.4-b01 * Generated source version: 2.2 * */ @WebService(name = "DayTimeService", targetNamespace = "http://timeservice/") @SOAPBinding(style = SOAPBinding.Style.RPC) public interface DayTimeService { /** * * @param arg0 * @return * returns java.lang.String */ @WebMethod @WebResult(partName = "return") @Action(input = "http://timeservice/DayTimeService/getServerTimeRequest", output = "http://timeservice/DayTimeService/getServerTimeResponse") public String getServerTime( @WebParam(name = "arg0", partName = "arg0") String arg0); /** * * @return * returns long */ @WebMethod @WebResult(partName = "return") @Action(input = "http://timeservice/DayTimeService/getUnixTimeRequest", output = "http://timeservice/DayTimeService/getUnixTimeResponse") public long getUnixTime(); }
package timeservice;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.4-b01
* Generated source version: 2.2
*
*/
@WebServiceClient(name = "DayTimeService", targetNamespace = "http://timeservice/", wsdlLocation = "http://127.0.0.1:5001/timeservice?wsdl")
public class DayTimeService_Service extends Service
{
private final static URL DAYTIMESERVICE_WSDL_LOCATION;
private final static WebServiceException DAYTIMESERVICE_EXCEPTION;
private final static QName DAYTIMESERVICE_QNAME = new QName("http://timeservice/", "DayTimeService");
static
{
URL url = null;
WebServiceException e = null;
try {
url = new URL("http://127.0.0.1:5001/timeservice?wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
DAYTIMESERVICE_WSDL_LOCATION = url;
DAYTIMESERVICE_EXCEPTION = e;
}
public DayTimeService_Service()
{
super(__getWsdlLocation(), DAYTIMESERVICE_QNAME);
}
public DayTimeService_Service(WebServiceFeature... features)
{
super(__getWsdlLocation(), DAYTIMESERVICE_QNAME, features);
}
public DayTimeService_Service(URL wsdlLocation)
{
super(wsdlLocation, DAYTIMESERVICE_QNAME);
}
public DayTimeService_Service(URL wsdlLocation, WebServiceFeature... features)
{
super(wsdlLocation, DAYTIMESERVICE_QNAME, features);
}
public DayTimeService_Service(URL wsdlLocation, QName serviceName)
{
super(wsdlLocation, serviceName);
}
public DayTimeService_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features)
{
super(wsdlLocation, serviceName, features);
}
/**
*
* @return
* returns DayTimeService
*/
@WebEndpoint(name = "DayTimeServiceImplPort")
public DayTimeService getDayTimeServiceImplPort()
{
return super.getPort(new QName("http://timeservice/", "DayTimeServiceImplPort"), DayTimeService.class);
}
/**
*
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.
Supported features not in the features
parameter will have their default values.
* @return
* returns DayTimeService
*/
@WebEndpoint(name = "DayTimeServiceImplPort")
public DayTimeService getDayTimeServiceImplPort(WebServiceFeature... features)
{
return super.getPort(new QName("http://timeservice/", "DayTimeServiceImplPort"), DayTimeService.class, features);
}
private static URL __getWsdlLocation()
{
if (DAYTIMESERVICE_EXCEPTION!= null)
{
throw DAYTIMESERVICE_EXCEPTION;
}
return DAYTIMESERVICE_WSDL_LOCATION;
}
}
Der Javaclient vereinfacht sich mit Hilfe der Datei nochmal.
public static void main(String[] args) throws IOException { System.out.println("DayTimeServiceClient"); Service service = new DayTimeService_Service(); DayTimeService dts = service.getPort(DayTimeService.class); System.out.println(dts.getServerTime("ge")); }