Webservices

Transcription

Webservices
1
5. Web-Services
• Kommunikation zwischen Client und Server
über XML-Format SOAP
Client
• Beschreibung von Webservices in WSDL
(Web Services Description Language)
Web Service Protokollstapel
Entdeckung
• Suche passender Dienste mit UDDI (Universal
Description, Discovery, and Integration)
• Potential: führende Integrationsinfrastruktur
(“kleinster gemeinsamer Nenner”)
SOAP
Server
UDDI
Beschreibung
WSDL
Verpackung
SOAP
Übertragung
HTTP, SMTP, FTP
2
5.1 SOAP
• XML-Format zur Übermittlung von Web-Service-Aufrufen und deren Antworten
SOAP−Envelope
SOAP−Header
Header−Block
Header−Block
SOAP−Body
Nachrichten−Body
3
Details zu SOAP
• bei Fehler: spezielle fault-Antwort (=
ˆ Exception)
• durch Header: u.a. optionale Zugangskontrolle, Transaktionsverwaltung
• Web-Services sind typischerweise zustandslos
• daher ggf. Zustand (z.B. Session-Id) als Parameter
• unübersichtliche XML-Struktur wird in Client- und Server-Code
durch Proxy-Klassen bzw. Webserver versteckt
• Implementierungen: z.B. Apache Axis (→ Tomcat), JAX-WS
4
Beispiel: SOAP-Anfrage
<?xml version=’1.0’ encoding=’UTF-8’?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://www.w3.org/2001/09/soap-envelope/"
xmlns:xsi="http//www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<ns1:getWeather
xmlns:ns1="urn:examples:weatherservice"
SOAP-ENV:encodingStyle="http://www.w3.org/2001/09/soap-encoding/">
<zipcode xsi:type="xsd:string">48149</zipcode>
</ns1:getWeather>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
(angelehnt an: E. Cerami: Web Services, O’Reilly, 2002)
5
Beispiel: SOAP-Antwort
<?xml version=’1.0’ encoding=’UTF-8’?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://www.w3.org/2001/09/soap-envelope/"
xmlns:xsi="http//www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<ns1:getWeatherResponse
xmlns:ns1="urn:examples:weatherservice"
SOAP-ENV:encodingStyle="http://www.w3.org/2001/09/soap-encoding/">
<return xsi:type="xsd:int">23</return>
</ns1:getWeatherResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
6
SOAP-Nachrichtenformate
• document: SOAP-Body ist beliebiges XML-Dokument (default)
• rpc: SOAP-Body enthält Methodenname und Parameter
• literal: Daten gemäß XML-Schema (XSD) strukturiert (default)
• encoded: verwendet vordefinierte XML-Tags für übliche Basistypen
(z.B. int, double) sowie Arrays und Structs
• typische Kombinationen: document/literal (empfohlen) und rpc/encoded
• kein verteiltes Objektmodell (anders als z.B. CORBA)
7
5.2 WSDL
• Format zur Beschreibung von Web-Services
<definitions>
<types>
Datentypen
<messages>
Nachrichten
<porttype>
Operationen
<binding>
Übertragungsprotokolle
<service>
Zugriffsadresse
8
Beispiel: WSDL-Beschreibung des Wetter-Web-Service
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="WeatherService"
targetNamespace="http://www.ecerami.com/wsdl/WeatherService.wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.ecerami.com/wsdl/WeatherService.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<message name="getWeatherRequest">
<part name="zipcode" type="xsd:string"/>
</message>
<message name="getWeatherResponse">
<part name="temperature" type="xsd:int"/>
</message>
<portType name="Weather PortType">
<operation name="getWeather">
<input message="tns:getWeatherRequest"/>
<output message="tns:getWeatherResponse"/>
</operation>
</portType>
9
<binding name="Weather Binding" type="tns:Weather PortType">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getWeather">
<soap:operation soapAction=""/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:examples:weatherservice"
use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:examples:weatherservice"
use="encoded"/>
</output>
</operation>
</binding>
<service name="Weather Service">
<documentation>WSDL File for Weather Service</documentation>
<port binding="tns:Weather Binding" name="Weather Port">
<soap:address
location="http://localhost:8080/soap/servlet/rpcrouter"/>
</port>
</service>
</definitions>
10
5.3 Web-Services mit .NET
• Web-Service-Klasse erbt von System.Web.Services.WebService
• bietet ggf. Properties Session, Application, Context, User (→ Zustand)
• Verweis auf Hintergrundcode in .asmx-Datei
<%@ WebService Language="C#" CodeBehind="MeinService.asmx.cs"
Class="..." %>
• deployed in MS Internet Information Server (IIS)
• Annotationen [WebService], [WebMethod], . . .
• (z.B.) Visual Studio erzeugt Client-Proxy-Klasse aus WSDL-Beschreibung
• Web-Service-Namen können nicht überladen werden
• fault-Antwort wird von Proxy in SoapException umgewandelt
11
Beispiel: Addier-Web-Service mit .NET
using System.Web.Services;
using System.Web.Services.Protocols;
...
namespace AddierService {
/// <summary>Dieser Webservice addiert zwei Zahlen.</summary>
[WebService(Namespace = "http://localhost/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1 1)]
public class Addierer : System.Web.Services.WebService {
[WebMethod(Description="Dieser Webservice addiert 2 Zahlen.")]
public int Addiere(int[] a) {
int summe = 0;
foreach(int x in a) summe += x;
return summe;}
}
}
12
Beispiel: Web-Service-Client mit .NET
using AddierService; ...
namespace AddierClientNSp {
public partial class AddierClient : System.Web.UI.Page {
public void Addiere(object sender, EventArgs ev) {
int[] val = new int[2];
val[0] = Convert.ToInt32(x.Text);
val[1] = Convert.ToInt32(y.Text);
// Projektname.Webverweisname.Service-Klasse
Addierservice.AddierWebService.Addierer service =
new Addierservice.AddierWebService.Addierer();
result.Text = "Ergebnis von .NET: " + service.Addiere(val);
Addierservice.AddierServiceEJB.AddiererIFService service2 =
new Addierservice.AddierServiceEJB.AddiererIFService();
try { result.Text += ", Ergebnis von Java-Web-Service: " +
service2.Addieren(val); }
catch (Exception e){Console.WriteLine(e.Message);}
}
}
}
13
Beispiel 2: Zustandsbehafteter Addier-Service mit .NET
...
namespace AddierService {
/// <summary> Webservice addiert Zahl zur bisherigen Summe.</summary>
[WebService(Namespace = "http://localhost/")]
[SoapRpcService(Use=SoapBindingUse.Encoded]
public class Addierer : System.Web.Services.WebService {
[WebMethod (EnableSession=true)]
public int Addiere(int x) {
int s;
try { s = (int) Session["Summe"]; }
catch (Exception) { s = 0; }
s += x;
Session["Summe"] = s;
return s;
}
}
}
14
Beispiel 2: Client zum zustandsbehafteten .NET-Web-Service
using System.Net;
...
namespace AddierClientNS {
public partial class AddierClient : System.Web.UI.Page{
public void Addiere(object sender, EventArgs ev){
int xval = Convert.ToInt32(x.Text);
CookieContainer cookieContainer;
if (Session["Cookie"] == null)
cookieContainer = new CookieContainer();
else cookieContainer = (CookieContainer)Session["Cookie"];
Addierservice.AddierWebService.Addierer service =
new Addierservice.AddierWebService.Addierer();
service.CookieContainer = cookieContainer;
result.Text = "Summe: " + service.Addiere(xval);
Session["Cookie"] = cookieContainer;}
}
}
15
Umwandlung zwischen .NET-Typen und XML-Schema-Typen
.NET-Typ
System.String
System.Boolean
System.Int16
System.Int32
System.Int64
System.Double
System.Byte
...
XML-Schema-Typ
string
boolean
short
int
long
double
unsignedbyte
...
16
5.4 Web-Services in Java
Beispiel: Wetter-Web-Service in Java
@Stateless
@WebService
public class WeatherService{
@WebMethod
public int getWeather(String zipcode) {
return 23;}
}
• wird deployed (z.B. in Webcontainer Tomcat)
• Annotationen @WebService und @WebMethod an Klasse bzw. Methode
• Vor.: stateless (!) Session-Bean (oder Servlet)
17
Zusätzliche Annotationen
• Annotation @OneWay an Methode mit Ergebnis void
• Klassen-Annotation zur Festlegung des Nachrichtenformats:
? @SOAPBinding(style= ..., use = ...)
? style: SOAPBinding.Style.RPC oder SOAPBinding.Style.DOCUMENT
? use: SOAPBinding.Use.LITERAL oder SOAPBinding.Style.ENCODED
18
Java-Client mit Dependency Injection
Beispiel: Stateless Session Bean als Client eines Webservice
@Stateless
@Resource(name="service/Addierer",
type ="javax.jws.WebService",
mappedName="AddiererService")
public class AddiererClient implements SomeInterface{
public int addiere(int x, int y){
int[] val = {x,y};
@WebServiceRef(name="java:comp/env/service/Addierer")
Addierer service;
return service.addiere(val);}
}
}
19
Beispiel: Session-Bean als Web-Service
package ejb;
import javax.jws.WebService;
...
@PermitAll
@Stateless
@Remote(AddiererIF.class)
@WebService(endpointInterface = "ejb.AddiererIF",
name = "AddiererIF")
@WebContext(contextRoot="/add4WS", secureWSDLAccess=false)
public class Addierer implements AddiererIF{
public int addieren(int x, int y) throws RemoteException{
return x+y;}
}
20
Beispiel: Interface zur Session-Bean
package ejb;
import javax.jws.WebService;
...
@WebService
@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
public interface AddiererIF extends Remote {
// Umbenennung wegen .NET-Namenskonventionen
@WebMethod(operationName="Addieren")
public int addieren(int x, int y) throws RemoteException;
}
21
Beispiel: Java-Servlet als Web-Service-Client
package servlets;
import webservicesEJB.*;
...
public class AddiererServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
int x = Integer.parseInt(req.getParameter("x"));
int y = Integer.parseInt(req.getParameter("y"));
int result = 0;
try {
AddiererService addiererService = new AddiererService();
AddiererServiceSOAP addierer = addiererService.getAddiererServiceSOAP();
result = addierer.addieren(x,y);}
catch (Exception e) {e.printStackTrace();}
// Ausgabe des Ergebnisses ...
}}
22
Erstellen der Proxy-Klassen
• die Proxyklassen zum Zugriff auf einen Web-Service (auch .NET) generiert (z.B.)
wsimport
• wsimport ist in JAX-WS enthalten
• Aufruf über die Kommandozeile:
1. (unter Windows:) Start → Ausführen, dann Öffnen: cmd
2. im erscheinenden Fenster mit cd in den gewünschten Ordner gehen
3. wsimport -Xendorsed -keep -extension <URL der WSDL-Datei>
4. z.B. wsimport ... http://localhost:8080/add4WS/Addierer?wsdl
5. das generierte Verzeichnis in den src-Ordner
des eclipse-Web-Service-Client-Projekts kopieren