WebService
Cet article vous montrera comment écrire un serveur web implémentant un WebService avec SOAP (Simple Object Access Protocol) en tirant partie du composant THTTPSoapPascalInvoker de Delphi 6

En effet, la dernière mouture de Delphi permet de créer un service web exploitant le protocole SOAP 1.1, sous forme de dll ISAPI ou comme extension pour serveur Apache par exemple. Ici, je vous propose de partir des composants Internet freeware de F. Piette (voir la rubrique Ressources), en particulier du projet d'exemple WebServ utilisant le composant THttpServer et permettant d'exécuter un serveur web.
SOAP définit un format d'échange de données XML reposant sur le protocole HTTP. Lorsqu'un client émet une requête vers un service web, il s'agit d'une requête HTTP de méthode POST dont l'entête contient l'élément SOAPAction et le corps le message XML obéissant à SOAP.
Pour une telle requête, l'événement OnPostedData du composant THttpServer est déclenché. On détermine si l'entête de la requête a le paramètre SOAPAction en le cherchant dans la liste des chaînes de caractères de la propriété RequestHeader de l'objet de type TMyHttpConnection. S'il existe une valeur pour ce paramètre, on considère qu'il s'agit d'une requête SOAP et la méthode TWebServForm.DispatchSOAP est déclenchée :

const DefException =
   '<?xml version="1.0" encoding=''UTF-8''?>' +
   '<SOAP-ENV:Envelope' + ' ' +
   'xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >' +
   '<SOAP-ENV:Body> ' +
   '<SOAP-ENV:Fault> ' +
   '<faultcode>SOAP-ENV:Server</faultcode>' +
   '<faultstring>%s</faultstring>' +
   '</SOAP-ENV:Fault>' +
   '</SOAP-ENV:Body>' +
   '</SOAP-ENV:Envelope>';

procedure TWebServForm.DispatchSOAP(Client: TMyHttpConnection; const SOAPAction: string);
var
    Stream: TStream;

    SoapPascalInv: THTTPSoapPascalInvoker;
    Request: TStringStream;
    Response: TMemoryStream;
    WResponse: WideString;

    procedure SendResponse;
    var
        Body: string;
        Header: string;
    begin
        Body := UTF8Encode(WResponse);
        Header := Client.Version + ' 200 OK' + #13#10 +
                  'Content-Type: text/xml' + #13#10 +
                  'Content-Length: ' +
                  IntToStr(Length(Body)) + #13#10 +
                  #13#10;
        Stream.Write(Header[1], Length(Header));
        Stream.Write(Body[1], Length(Body));
        Stream.Seek(0, 0);
        { Ask HTTP server component to send data stream for us }
        Client.DocStream := Stream;
        Client.SendStream;
    end;

begin
    try
        try
            Response := TMemoryStream.Create;
            try
                SoapPascalInv := THTTPSoapPascalInvoker.Create(nil);
                Request := TStringStream.Create(Client.FPostedDataBuffer);
                try
                    SoapPascalInv.DispatchSOAP('/soap', SOAPAction, Request, Response);
                finally
                    Request.Free;
                    SoapPascalInv.Free;
                end;

                { Now create output stream to send back to remote client }
                Stream := TMemoryStream.Create;
                SetLength(WResponse, Response.Size div 2);
                Response.Read(WResponse[1], Response.Size);

                SendResponse;
            finally
                Response.Free;
            end;
        except
            on E: Exception do
            begin
                WResponse := Format(DefException, [E.Message]);
                SendResponse;
            end;
        end;
    except
        on E: Exception do;
    end;
end;


Cette méthode crée un objet THTTPSoapPascalInvoker de manière à permettre l'appel de toute interface invoquable rencencée dans l'application avec l'exécution de sa méthode DispatchSOAP. Le troisième argument de cette méthode permet d'obtenir la réponse SOAP sous forme de flux TStream ; si il n'y a pas d'exception, ces données sont ensuite envoyées au client.


Ressources

ICS (Internet Component Suite) de F. Piette

Sommaire

Ressources

Début

Copyright © 2003 OBJECT-EVERYWHERE. Tous droits réservés | Bertrand Goetzmann