Hallo,
hier ein Beispiel mit zum Aufruf eines Java Webservices mit C# mittels JAX-WS auf der Java Seite.
Vorteile dieses Ansatzes sind, dass man u.a. keine Third-Party Bibliotheken braucht
und einen etablierten Standard (JAX-WS) verwendet. Darüber hinaus ist die Implementierung IMHO relativ einfach.
Unser PingWebServiceInterface:
Java:
package de.tutorials.training.jaxws;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface PingWebService {
@WebMethod
String process(String request);
}
Unsere Webservice Implementierung:
Java:
package de.tutorials.training.jaxws;
import javax.jws.WebService;
@WebService(endpointInterface = "de.tutorials.training.jaxws.PingWebService")
public class DefaultPingWebService implements PingWebService {
public String process(String request) {
System.out.println("Got Request: " + request);
String response = null;
if("ping".equals(request)){
response = "pong";
}else{
response = "unknownRequest: " + request;
}
return response;
}
}
Unser Java "Server":
Java:
package de.tutorials.training.jaxws;
import java.net.InetAddress;
import javax.xml.ws.Endpoint;
public class PingWebServiceExample {
public static void main(String[] args) throws Exception {
String address = "http://" + InetAddress.getLocalHost().getHostName() + ":44444/ping";
Endpoint endpoint = Endpoint.publish(address, new DefaultPingWebService());
System.out.println("Service Published @ " + address );
System.out.println("Service WSDL @ " + address +"?wsdl");
}
}
Unser .net Client:
1) Neues Visual C# (Konsolen)-Projekt erstellen.
2) Dienstverweis hinzufügen
3) URL:
http://_HOSTNAME_:44444/ping?wsdl angeben -> Gehe zu.
in der Konfigurationsdatei app.config kann man unter configuration/system.serviceModel/client/endpoint -> über das address Attribut den Hostname anpassen.
4) Namespace De.Tutorials.WS angeben. Nach dem klick auf "Ok" wird eine entsprechende Klassenstruktur (je nach Konfiguration WebService Proxy, Request / Responses) für den Webservice Client generiert.
5) Anschließend folgenden Code in Progam.cs hinterlegen.
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Training.De.Tutorials.WS;
namespace Training
{
class Program
{
static void Main(string[] args)
{
PingWebServiceClient service = new PingWebServiceClient();
Console.WriteLine("Got Response: " + service.process("ping"));
}
}
}
... wenn ein WebService auf der Java Seite erweitert wurde, kann man über das Kontext-Menü (nach Selektion des entsprechenden Dienst-Verweises), den Dienst-Verweis aktualisieren - dabei werden dann ggf. auch neue Klassen generiert.
... du kannst natürlich auch komplexere Objekt Strukturen als Parameter / Rückgabe verwenden.
Dabei werden dann für die Strukturen vom JAX-WS Laufzeit System dynamisch entsprechende XML Schema Definitionen generiert.
hier mal anhand eines weiteren WebServices der einen System Status ermittelt und dazu entsprechende Request / Response Strukturen definiert.
Unser StatusWebService interface:
Java:
package de.tutorials.training.jaxws;
import javax.jws.WebMethod;
@WebService
public interface StatusWebService {
@WebMethod
StatusResponse getStatus(StatusRequest request);
}
Unsere StatusWebService Implementierung:
Java:
package de.tutorials.training.jaxws;
import javax.jws.WebService;
@WebService(endpointInterface="de.tutorials.training.jaxws.StatusWebService")
public class DefaultStatusWebService implements StatusWebService{
@Override
public StatusResponse getStatus(StatusRequest request) {
System.out.println("Sending Server status to client: " + request.getClientId());
StatusResponse response = new StatusResponse();
response.setSystemStatus(querySystemStatus());
return response;
}
private SystemStatusCode querySystemStatus() {
return SystemStatusCode.READY;
}
}
Request:
Java:
package de.tutorials.training.jaxws;
import java.io.Serializable;
public class Request implements Serializable{
private static final long serialVersionUID = 1L;
}
StatusRequest:
Java:
package de.tutorials.training.jaxws;
public class StatusRequest extends Request{
private static final long serialVersionUID = 1L;
private String clientId;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
}
Response:
Java:
package de.tutorials.training.jaxws;
import java.io.Serializable;
public class Response implements Serializable {
private static final long serialVersionUID = 1L;
}
StatusResponse:
Java:
package de.tutorials.training.jaxws;
public class StatusResponse extends Response{
private static final long serialVersionUID = 1L;
private SystemStatusCode systemStatus;
public SystemStatusCode getSystemStatus() {
return systemStatus;
}
public void setSystemStatus(SystemStatusCode systemStatus) {
this.systemStatus = systemStatus;
}
}
SystemStatusCode Enum:
Java:
package de.tutorials.training.jaxws;
public enum SystemStatusCode {
STARTING,READY, STOPPING;
}
Den StatusWebService können wir gemeinsam mit dem Ping Webservice betreiben:
Java:
package de.tutorials.training.jaxws;
import java.net.InetAddress;
public class WebServiceExample {
public static void main(String[] args) throws Exception {
String address = "http://" + InetAddress.getLocalHost().getHostName() + ":44444/ping";
Endpoint.publish(address, new DefaultPingWebService());
System.out.println("Service Published @ " + address );
System.out.println("Service WSDL @ " + address +"?wsdl");
address = "http://" + InetAddress.getLocalHost().getHostName() + ":44444/status";
Endpoint.publish(address, new DefaultStatusWebService());
System.out.println("Service Published @ " + address);
System.out.println("Service WSDL @ " + address +"?wsdl");
}
}
Hier der angepasste .Net Client in C#.
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Training.De.Tutorials.WS;
using Training.De.Tutorials.WS.Status;
namespace Training
{
class Program
{
static void Main(string[] args)
{
PingWebServiceClient service = new PingWebServiceClient();
Console.WriteLine("Got Response: " + service.process("ping"));
StatusWebServiceClient statusService = new StatusWebServiceClient();
statusRequest request = new statusRequest();
request.clientId = Guid.NewGuid().ToString();
statusResponse response = statusService.getStatus(request);
Console.WriteLine("System Status: "+ response.systemStatus);
}
}
}
Btw. die Namen für die generierten Klassen / Attribute kann man auf der Java Seite über entsprechende JAXB Annotationen (@XmlType, @XmlElement, etc.) beeinflussen.
Die Namen der WebService Klassen / Methoden lassen sich über die @WebService / @WebMethod Annotation steuern.
;-)
Gruß Tom