Les Services Web: Principes et Implémentation

Un Service Web est une technologie de calcul distribué basée sur le Web qui permet à différentes applications de communiquer et d'échanger des données via un réseau. Les Services Web utilisent des protocoles Web standards (HTTP/HTTPS) et le format XML pour le transfert de données, offrant ainsi des caractéristiques de multiplateforme et de multi-langage.

Caractéristiques Fondamentales des Services Web

  • Interopérabilité : Les applications développées sur différentes plateformes et dans différents langages peuvent s'appleer mutuellement
  • Standardisation : Basé sur des standards ouverts comme XML, SOAP, WSDL
  • Couplage Faible : Les fournisseurs et consommateurs de services interagissent via des interfaces
  • Extensibilité : Prend en charge le déploiement et l'extension distribués

Stack Technologique des Services Web


┌─────────────────────────────────────┐
│        Stack Technologique des       │
│             Services Web            │
├─────────────────────────────────────┤
│  SOAP (Protocole d'Accès aux Objets)│
│  WSDL (Langage de Description de WS)│
│  UDDI (Universal Description,      │
│        Discovery and Integration)   │
│  XML (Langage de Balisage Extensible)│
│  HTTP/HTTPS (Protocole de transport)│
└─────────────────────────────────────┘

Protocole SOAP en Détail

SOAP (Simple Object Access Protocol) est le protocole central des Services Web, définissant comment échanger des informations structurées sur le réseau.

Structure d'un Message SOAP :


<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <!-- Informations d'en-tête optionnelles -->
    </soap:Header>
    <soap:Body>
        <!-- Corps du message contenant les données métier -->
        <ns1:recupererDonneePatient xmlns:ns1="http://www.exemple.com/">
            <numeroDossier>12345</numeroDossier>
        </ns1:recupererDonneePatient>
    </soap:Body>
</soap:Envelope>

Analyse de Document WSDL

WSDL (Web Services Description Language) est le langage de description des Services Web, définissant les interfaces, méthodes, paramètres et valeurs de retour du service.

Structure d'un Document WSDL :


<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://www.exemple.com/">
    
    <!-- Définitions de types -->
    <types>
        <xsd:schema targetNamespace="http://www.exemple.com/">
            <xsd:element name="recupererDonneePatient">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="numeroDossier" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:schema>
    </types>
    
    <!-- Définitions de messages -->
    <message name="recupererDonneePatientRequest">
        <part name="parameters" element="tns:recupererDonneePatient"/>
    </message>
    
    <!-- Définitions de types de port -->
    <portType name="ServicePatientPortType">
        <operation name="recupererDonneePatient">
            <input message="tns:recupererDonneePatientRequest"/>
            <output message="tns:recupererDonneePatientResponse"/>
        </operation>
    </portType>
    
    <!-- Définitions de liaison -->
    <binding name="ServicePatientBinding" type="tns:ServicePatientPortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="recupererDonneePatient">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    
    <!-- Définitions de service -->
    <service name="ServicePatientService">
        <port name="ServicePatientPort" binding="tns:ServicePatientBinding">
            <soap:address location="https://ADRESSE_IP/csp/hsb/SERVICE.Patient.BS.ServicePatient.cls"/>
        </port>
    </service>
</definitions>

Étape 1 : Obtenir l'Adresse WSDL


Adresse de l'interface fournie par l'hôpital :
http://URL_Sante/SERVICE.NetComService.cls

Où URL_Sante = http://ADRESSE_IP/imedical/web

L'adresse complète est donc :
http://ADRESSE_IP/imedical/web/SERVICE.NetComService.cls?WSDL

Étape 2 : Générer le Code Client


# Utiliser l'outil Axis2 pour générer le code client
wsdl2java -uri "http://ADRESSE_IP/imedical/web/SERVICE.NetComService.cls?WSDL" \
          -p com.entreprise.service \
          -o src

Les fichiers générés : ```

src/com/entreprise/service/ ├── ServiceNetComStub.java ← Classe cliente principale ├── ServiceNetComCallbackHandler.java ← Classe de rappel asynchrone ├── SoumissionDemande.java ← Objet de demande ├── SoumissionDemandeReponse.java ← Objet de réponse └── Autres classes d'assistance...


### Étape 3 : Implémenter la méthode recupererInfosPatient

@Override public List<InfoPatient> recupererInfosPatient(String entree) { List<InfoPatient> listeResultats = new ArrayList<InfoPatient>

try {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date date = new Date();
    String dateCourante = format.format(date).substring(0, 10);
    String heureCourante = format.format(date).substring(11, 19);
    
    // Enregistrement du certificat HTTPS (si nécessaire)
    Protocol.registerProtocol("https", new Protocol("https", new NeoSecureSocketFactory(), 443));
    
    // 1. Création du client Service Web
    ServiceNetComStub stub = new ServiceNetComStub();
    
    // 2. Construction de l'objet demande
    SoumissionDemande demande = new SoumissionDemande();
    demande.setCodeDemande("xxxxx");  // Code métier :
    demande.setXmlDemande(
        "<Demande>" +
        "<NumeroPatient>" + entree + "</NumeroPatient>" +
        "<locId>370</locId>" +
        "</Demande>"
    );
    
    System.err.println("Demande d'informations patient : " + demande.getXmlDemande());
    logger.info("Demande d'informations patient : " + demande.getXmlDemande());
    
    // 3. Envoi de la demande
    SoumissionDemandeReponse reponse = stub.soumettreDemande(demande);
    String chaineRetour = reponse.getResultatSoumissionDemande();
    
    System.err.println("Réponse d'informations patient : " + chaineRetour);
    logger.info("Réponse d'informations patient : " + chaineRetour);
    
    // 4. Analyse de la réponse
    Document doc = DocumentHelper.parseText(chaineRetour);
    Element racine = doc.getRootElement();
    
    // 5. Vérification du résultat
    String codeResultat = racine.elementText("CodeResultat");
    if ("0".equals(codeResultat)) {
        // Analyse des données d'enregistrement de consultation
        Element enregistrementConsultation = racine.element("EnregistrementConsultation");
        if (enregistrementConsultation != null) {
            // Analyse de la ListeItemsPE
            Element listeItemsPE = enregistrementConsultation.element("ListeItemsPE");
            if (listeItemsPE != null) {
                List<Element> itemsPEOrdre = listeItemsPE.elements("ItemPEOrdre");
                for (int j = 0; j < itemsPEOrdre.size(); j++) {
                    Element itemPEOrdre = itemsPEOrdre.get(j);
                    if (itemPEOrdre.elementText("descriptionItem").contains("13 carbone")) {
                        InfoPatient info = new InfoPatient();
                        
                        // Informations de base
                        info.setNomPatient(enregistrementConsultation.elementText("nomPatient"));
                        info.setSexe(enregistrementConsultation.elementText("descriptionSexe"));
                        
                        // Traitement de l'âge (suppression du mot "ans")
                        String chaineAge = enregistrementConsultation.elementText("agePatient");
                        if (chaineAge.contains("ans")) {
                            chaineAge = chaineAge.substring(0, chaineAge.indexOf("ans"));
                        }
                        info.setAge(Integer.valueOf(chaineAge));
                        
                        // Numéro d'enregistrement et ID de consultation
                        info.setNumeroLit(entree);  // Numéro d'enregistrement
                        info.setHistorique(enregistrementConsultation.elementText("idConsultation"));  // ID de consultation
                        
                        // Informations du service
                        info.setDepartement(enregistrementConsultation.elementText("descriptionService"));
                        
                        // Informations de prescription médicale
                        info.setIdItemPrescription(itemPEOrdre.elementText("idItem"));  // ID de prescription
                        info.setIdExamen(itemPEOrdre.elementText("descriptionItem"));    // Nom de l'examen
                        
                        // Détails de l'examen
                        Element listeDetails = itemPEOrdre.element("listeDetails");
                        if (listeDetails != null) {
                            Element detailPrescription = listeDetails.element("DetailPrescription");
                            if (detailPrescription != null) {
                                info.setIdVerification(detailPrescription.elementText("idDetail"));  // ID de l'item de prescription
                                info.setCodeUpdateUtilisateur(detailPrescription.elementText("descriptionDetail"));  // Description de l'item
                            }
                        }
                        
                        // Ajout à la liste (insertion en première position)
                        listeResultats.add(0, info);
                    }
                }
            }
        }
    }
    
} catch (Exception e) {
    e.printStackTrace();
    logger.error(e);
}

return listeResultats;

}


### Étape 4 : Implémenter la methode genererRapport

public String genererRapport(EtatGaz obj) { if ((obj.getNumeroLit() != null) && (!obj.getNumeroLit().equals(""))) { try { // 1. Création du client Service Web ServiceNetComStub stub = new ServiceNetComStub();

        // 2. Construction de l'objet demande
        SoumissionDemande demande = new SoumissionDemande();
        demande.setCodeDemande("xxxx");  // Code métier :
        demande.setXmlDemande(
            "<Demande>" +
            "<IDConsultation>" + obj.getHistorique() + "</IDConsultation>" +
            "<ListeResultatsItem>" +
            "<ItemExamen>" +
            "<DescriptionItem>" + obj.getIdExamen() + "</DescriptionItem>" +
            "<IdItem>" + obj.getIdItemPrescription() + "</IdItem>" +
            "<FormatRapport>jpg</FormatRapport>" +
            "<MedecinValidation>" + obj.getVerificateur() + "</MedecinValidation>" +
            "<MedecinControle>" + obj.getVerificateur() + "</MedecinControle>" +
            "<DateExamen>" + obj.getTempsVerification() + "</DateExamen>" +
            "<ListeDetailsItem>" +
            "<DetailItemExamen>" +
            "<IdDetail>" + obj.getIdVerification() + "</IdDetail>" +
            "<DescriptionDetail>Test C13</DescriptionDetail>" +
            "<Abreviation>C13</Abreviation>" +
            "<ResultatDetail>" + obj.getValeurDOB() + "</ResultatDetail>" +
            "<IndicateurNormal>" + (obj.getValeurDOB() < 4.0 ? "N" : "H") + "</IndicateurNormal>" +
            "<UniteDetail>DOB</UniteDetail>" +
            "<PlageReference>0-4</PlageReference>" +
            "<InfoImage>https://172.30.10.20:1443/dhccftp/peftp" + 
            Parametrage.getInstance(rappel).getCheminFtp() + obj.getNumeroLit() + ".jpg</InfoImage>" +
            "</DetailItemExamen>" +
            "</ListeDetailsItem>" +
            "</ItemExamen>" +
            "</ListeResultatsItem>" +
            "</Demande>"
        );
        
        // 3. Envoi de la demande
        SoumissionDemandeReponse reponse = stub.soumettreDemande(demande);
        String resultat = reponse.getResultatSoumissionDemande();
        
        // 4. Analyse de la réponse
        Document doc = DocumentHelper.parseText(resultat);
        Element racine = doc.getRootElement();
        String codeResultat = racine.elementText("CodeResultat");
        
        if ("0".equals(codeResultat)) {
            return "0";
        } else {
            return resultat;
        }
        
    } catch (Exception e) {
        e.printStackTrace();
    }
}

return "";

}


### Sécurité et Authentification

#### 4.1 Gestion des Ceritficats HTTPS

Dans le dévelopement de Services Web, il est souvent nécessaire de gérer la validation des certificats HTTPS. Voici plusieurs solutions courantes :

##### Vérification de certificat personnalisée

public class NeoSecureSocketFactory extends SSLSocketFactory {

private SSLContext sslContext = SSLContext.getInstance("TLS");

public NeoSecureSocketFactory() throws Exception {
    super(null);
    sslContext.init(null, new TrustManager[]{new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] chain, String authType) {}
        public void checkServerTrusted(X509Certificate[] chain, String authType) {}
        public X509Certificate[] getAcceptedIssuers() { return null; }
    }}, new SecureRandom());
}

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) 
        throws IOException {
    return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}

}


##### Importation de certificat

Importer le certificat serveur dans la base de confiance Java

keytool -import -alias-certificat-serveur -fichier certificat.crt -keystore $JAVA_HOME/jre/lib/security/cacerts


</div></div>

Étiquettes: SOAP WSDL WebService XML HTTPS

Publié le 7 juillet à 19h23