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>