Communication entre .NET et J2EE

Par Julien Chable, développeur/consultant chez Wygwam France sur les technologies Office, Open XML et SharePoint.

Blog de Julien.

Aujourd’hui lorsque l’on parle de système d’information ou d’infrastructure, nous voulons souvent exprimer le fait que cet ensemble de machines et de logiciels applicatifs représente un environnement de nature hétérogène. Rare sont les entreprises qui ont des SI utilisant uniquement  un environnement propriétaire complet, par exemple IBM, Sun ou Microsoft. L’hétérogénéité est donc une réalité commune pour les entreprises qui doivent souvent faire face à la complexité que cela peut entrainer. L’arrivé des web services constitue une nouvelle tentative, après CORBA, DCOM, RMI, d’adresser cette problématique et d’y répondre le plus élégamment possible en utilisant les technologies à notre disposition tel que le web HTTP et le XML. Cependant les Web Service ne représentent pas le seul moyen de pouvoir comme nous le verrons dans cet article.

Malgré l’inertie d’une grande entreprise, la mentalité de Microsoft a beaucoup évolué en 10 ans, que ce soit au niveau de l’ouverture de ses protocoles que dans l’utilisation des différents standards dans ses produits. Microsoft a d’ailleurs été l’un des principaux incitateurs et pionners des Services Web, de l’utilisation du XML et plus récemment de nouveaux formats de fichier. Le framework .NET et la brique de communication Windows Communication Foundation ne pouvait pas être autrement que conforme aux standards en vigueur.

Cet article est l’occasion de voir ensemble qu’une solution créée en .NET et une autre avec la plateforme J2EE peuvent tout à fait communiquer en ayant recours à différentes techniques.

Echanger en utilisant la sérialisation

La sérialisation est le processus par lequel un objet ou une classe peut être encodé dans une forme pouvant être persistée et transportable. Cela est très utile puisque le média de persistance peut très bien être un fichier, la mémoire de la machine, une base de données, le réseau, etc. Il existe deux types de sérialisation : la sérialisation binaire et la sérialisation XML. Dans le premier cas, l’objet est transformé en flux d’octets, dans le second cas, en document XML.

L’opération inverse s’appelle la désérialisation, et représente le processus de restauration d’un objet sérialisé dans sa forme d’origine.

La sérialisation binaire

Les deux technologies, Java et .NET permettent de réaliser de la sérialisation binaire très simplement. Le code suivant écrit en Java et .NET permettant de sérialiser et de désérialiser un objet sous forme binaire est présenté plus bas.

Code Java :

import java.io.Serializable;

public class Produit implements Serializable {

     public String nom; 

     public String description;

     public double prix;

    @Override
    public String toString() {
        return nom + " - " + description + " - " + prix;
    }
}

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;


public class SerialisationBinaire {

    public static void main(String[] args) throws Exception {
        Produit produit = new Produit();
        produit.nom = "Interoperabilité à tout prix";
        produit.description = "Un très bon livre pour mieux comprendre l'interopérabilité";
        produit.prix = 30.00;

        System.out.println("Serialisation d'un produit " + produit);

        FileOutputStream fsOut = new FileOutputStream("produit.ser");
        ObjectOutputStream objStrOut = new ObjectOutputStream(fsOut);
        objStrOut.writeObject(produit);
        objStrOut.close();

        // On supprime le produit de la mémoire
        produit = null;

        System.out.println("Le produit a ete serialise !");
        System.out.println("Debut de la deserialisation ...");

        FileInputStream fsIn = new FileInputStream("produit.ser");
        ObjectInputStream objStrIn = new ObjectInputStream(fsIn);
        produit = (Produit)objStrIn.readObject();
        objStrIn.close();

        System.out.println("Le produit a ete deserialise : " + produit);
    }
}

Code .NET :

using System;

namespace Serialisation
{
    [Serializable]
    public class Produit
    {
        public string Nom;

        public string Description;

        public double Prix;

        public override string ToString()
        {
            return Nom + " - " + Description + " - " + Prix;
        }
    }
}

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Serialisation
{
    class Program
    {
        public static void Main(string[] args)
        {
            Produit produit = new Produit();
            produit.Nom = "Interoperabilité à tout prix";
            produit.Description = "Un très bon livre pour mieux comprendre l'interopérabilité";
            produit.Prix = 30.00;

            Console.WriteLine(String.Format("Serialisation d'un produit {0} ...", produit));

            IFormatter formatter = new BinaryFormatter();
            using (Stream fs = new FileStream("produit.ser", FileMode.Create))
            {
                formatter.Serialize(fs, produit);
            }

            // On supprime le produit
            produit = null;

            Console.WriteLine("Le produit a ete serialise !");
            Console.WriteLine("Debut de la deserialisation ...");

            using (Stream fs = new FileStream("produit.ser", FileMode.Open))
            {
                produit = (Produit)formatter.Deserialize(fs);
            }

            Console.WriteLine(String.Format("Le produit a ete deserialise : {0}", produit));

            Console.ReadLine();
        }
    }
}

Cependant, vous devez en en doutez quelque peu, les sérialiseurs binaire fournies par les deux plateformes ne sont pas compatible entre eux, chacun encodant en binaire selon ses principes.  Ainsi si vous essayez de sérialiser un objet Java puis de le désérialiser dans une application .NET, ou vice-versa, vous devrier observer la levée d’une exception de type StreamCorruptedException pour Java et SerializationException pour .NET.

Pour autant est-ce que cela veut dire qu’il ne peut y avoir interopérabilité dans la sérialisation binaire entre Java et .NET. Même si les implémentations par défaut des sérialiseurs Java et .NET ne sont pas compatible, la réponse est NON ! En effet, chaque plateforme permet de définir une sérialisation personnalisée des objets, ce qui devrait vous permettre de pouvoir définir la façon de sérialiser/désérialiser vos objets. Vous pouvez également utiliser des produits tel que Ja.NET qui fournit une version du sérialiseur .NET en Java.

Cependant, nous n’allons pas pousser plus loin l’investigation mais simplement continuer avec la sérialisation XML qui va nous permettre d’aller beaucoup plus loin et permettre de communiquer pleinement entre les deux plateformes. Cet exemple de sérialisation binaire va nous servir de point de départ dans notre réflexion.

La sérialisation XML

La différence avec la sérialisation binaire tient du fait que la sérialisation XML encode un objet sous la forme d’une structure XML et non binaire. XML étant une technologie manipulable par la plupart des plateformes, Java et .NET notamment, l’exploitation ou la génération des données sera plus simple à réaliser.

En .NET nous utiliserons la classe XmlSerializer pour transformer notre objet en XML, alors que Java fera appel à la sérialisation JavaBeans situé dans l’espace de nom java.beans.

Regardons un exemple de code Java et .NET de sérialisation XML pour une commande de produits (utilisant la classe Produit déjà utilisée) :

Code Java :

Remarque :Attention pour être sérialisable au format XML, vos classes doivent se conformer aux quatre points suivants :

  • Un constructeur par défaut (sans paramètres)
  • La classe doit implémenter l'interface Serializable
  • Toutes les propriétés que vous devez enregistrer doivent avoir des accesseurs (get/set)
  • Etre une classe publique

C’est pourquoi nous présentons une nouvealle définition de la classe Produit avec l’ensemble des getters/setters.

import java.io.Serializable;


@SuppressWarnings("serial")
public class Produit implements Serializable {

     public String nom; 

     public String description;

     public double prix;

    public String getNom() {
        return nom;
    }

    public void setNom(String nom) {
        this.nom = nom;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getPrix() {
        return prix;
    }

    public void setPrix(double prix) {
        this.prix = prix;
    }

    @Override
    public String toString() {
        return nom + " - " + description + " - " + prix;
    }
}

import java.util.ArrayList;

@SuppressWarnings("serial")
public class Commande extends ArrayList<Produit> {

}

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;


public class SerialisationXML {

    public static void main(String[] args) throws Exception {
        Produit produit1 = new Produit();
        produit1.nom = "Interoperabilité à tout prix";
        produit1.description = "Un très bon livre pour mieux comprendre l'interopérabilité";
        produit1.prix = 30.00;
        
        Produit produit2 = new Produit();
        produit2.nom = "Interoperabilite pour les nuls";
        produit2.description = "Un très bon livre pour commencer son apprentissage en douceur de l'interoperabilit";
        produit2.prix = 20.00;

        // Création de la liste des produits
        Commande produits = new Commande();
        produits.add(produit1);
        produits.add(produit2);

        System.out.println("Serialisation d'une commande " + produits);

        FileOutputStream fsOut = new FileOutputStream("commande.xml");
        ObjectOutputStream objStrOut = new ObjectOutputStream(fsOut);
        XMLEncoder xmlEncoder = new XMLEncoder(objStrOut);
        xmlEncoder.writeObject(produits);
        xmlEncoder.close();

        // On supprime le produit de la mémoire
        produit1 = null;
        produit2 = null;
        produits = null;

        System.out.println("La commande a ete serialise !");
        System.out.println("Debut de la deserialisation ...");

        FileInputStream fsIn = new FileInputStream("commande.xml");
        ObjectInputStream objStrIn = new ObjectInputStream(fsIn);
        XMLDecoder xmlDecoder = new XMLDecoder(objStrIn);
        produits = (Commande)xmlDecoder.readObject();
        xmlDecoder.close();

        System.out.println("Le produit a ete deserialise : " + produits);
    }
}

Code .NET :

public class Commande : List<Produit>
    {
        [XmlRoot("Produits")]
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (Produit produit in this)
            {
                sb.Append(produit + " / ");
            }
            return sb.ToString();
        }
    }

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Xml.Serialization;

namespace Serialisation_XML
{
    class Program
    {
        static void Main(string[] args)
        {
            // Création des produits
            Produit produit1 = new Produit();
            produit1.Nom = "Interoperabilité à tout prix";
            produit1.Description = "Un très bon livre pour mieux comprendre l'interopérabilité";
            produit1.Prix = 30.00;

            Produit produit2 = new Produit();
            produit2.Nom = "Interoperabilite pour les nuls";
            produit2.Description = "Un très bon livre pour commencer son apprentissage en douceur de l'interoperabilit";
            produit2.Prix = 20.00;

            // Création de la liste des produits
            Commande produits = new Commande();
            produits.Add(produit1);
            produits.Add(produit2);

            Console.WriteLine(String.Format("Serialisation d'une commande {0} ...", produits));

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Commande));
            using (Stream fs = new FileStream("commande.ser", FileMode.Create))
            {
                xmlSerializer.Serialize(fs, produits);
            }

            // On supprime les produits et la commande
            produit1 = null;
            produit2 = null;
            produits = null;

            Console.WriteLine("La commande a ete serialise !");
            Console.WriteLine("Debut de la deserialisation ...");

            using (Stream fs = new FileStream("commande.ser", FileMode.Open))
            {
                produits = (Commande)xmlSerializer.Deserialize(fs);
            }

            Console.WriteLine(String.Format("La commande a ete deserialise : {0}", produits));

            Console.ReadLine();
        }
    }
}

Voici le résultat pour l’application .NET :

<?xml version="1.0" ?> 
<Produits xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Produit>
        <Nom>Interoperabilité à tout prix</Nom> 
        <Description>Un très bon livre pour mieux comprendre l'interopérabilité</Description> 
        <Prix>30</Prix> 
    </Produit>
    <Produit>
        <Nom>Interoperabilite pour les nuls</Nom> 
        <Description>Un très bon livre pour commencer son apprentissage en douceur de l'interoperabilit</Description> 
        <Prix>20</Prix> 
    </Produit>
</Produits>

Et voici le résultat pour l’application Java :

<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_03" class="java.beans.XMLDecoder"> 
 <object class="Commande"> 
  <void method="add"> 
   <object class="Produit"> 
    <void property="description"> 
     <string>Un très bon livre pour mieux comprendre l&apos;interopérabilité</string> 
    </void> 
    <void property="nom"> 
     <string>Interoperabilité à tout prix</string> 
    </void> 
    <void property="prix"> 
     <double>30.0</double> 
    </void> 
   </object> 
  </void> 
  <void method="add"> 
   <object class="Produit"> 
    ...
   </object> 
  </void> 
 </object> 
</java>

Evidemment nous pourrons retrouver assez aisément les différentes objets et données des propriétés. Cependant, la structure XML diffère excessivement de celle générée par le sérialiseur XML de .NET. Pour résoudre ce problème, nous allons utiliser une librairie open source (licence BSD) nommée XStream (que vous pouvez télécharger à l’adresse suivante : http://xstream.codehaus.org/) qui va se charger de formatter le XML d’une façon plus .NETtienne.

XStream xstream = new XStream();
xstream.alias("Produits", Commande.class);
xstream.alias("Produit", Produit.class);
String decl = "\n";
String xml = xstream.toXML(produits);
System.out.print(decl + xml);

Voici le résultat :

<Produits serialization="custom">
  <unserializable-parents/>
  <list>
    <default>
      <size>2</size>
    </default>
    <int>10</int>
    <Produit>
      <nom>Interoperabilité à tout prix</nom>
      <description>Un très bon livre pour mieux comprendre l&apos;interopérabilité</description>
      <prix>30.0</prix>
    </Produit>
    <Produit>
      <nom>Interoperabilite pour les nuls</nom>
      <description>Un très bon livre pour commencer son apprentissage en douceur de l&apos;interoperabilit</description>
      <prix>20.0</prix>
    </Produit>
  </list>

Nous sommes déjà beaucoup plus proches d’une structure XML élégante et proche de celle du .NET : les éléments Produit possède une structure presque identique. La différence est due à la convention de nommage Java qui stipule que le nom des propriétés soit en minuscule alors que les développeurs .NET préfèrent utiliser des noms commençant par une majuscule. Nous choisissons d’adapter la convention Java à celle de .NET et de mettre tous les noms de propriétés en majuscule pour le besoin de cet article.

Maintenant que nous avons une structure XML, il va être simple de pouvoir retrouver nos Produit dans une Commande à l’aide de simple commande XPath ou d’API XML. NEANMOINS, si jamais une personne modifie un objet métier dans une des deux applications que va-t-il se passer ? Comment pourrait-on faire en sorte de garantir la consistance de la structure XML et avoir une structure identique permettant aussi bien la sérialisation .NET et Java ?

Ces questions trouvent leur réponse dans l’utilisation d’un contrat. Un contrat intermédiaire que l’on appelle plus souvent schéma dans le jargon XML. Un schéma sert à valider la structure d’un document XML, c'est-à-dire de vérifier la présence, la hiérarchie, le nombre d’occurrences, etc des éléments d’une structure XML.

Jusqu’à présent nous élaborions la classe Produit au mieux dans chacune des applications, une pour Java et l’autre pour .NET, néanmoins pour des structures complexes – et même simple comme on a pu le constater – la structure est rarement la même. Nous allons donc prendre le problème à l’envers et non plus partir d’une implémentation à partir de chacune des plateformes, mais partir du contrat et générer les classes nécessaires pour chaque plateforme. De cette façon, si demain vous utilisez une autre technologie, cette énième plateforme sera capable de supporter l’échange de données des applications Java et/ou .NET.

Voici le schéma XML que nous allons utiliser dans la suite de l’article :

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
    <xs:element name="Produits">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="Produit">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Nom" type="xs:string" />
                            <xs:element name="Description" type="xs:string" />
                            <xs:element name="Prix" type="xs:float" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xsd:schema>

Utiliser un schéma XML pour la sérialisation

Générer des classes en Java

Dans le cadre du projet Metro, dont nous reparlerons tout de suite après, le projet JAXB (Java API for XML Binding) permet de faire un réel mapping XML/Objets et de gén


Copyright "Ed Ort and Bhakti Mehta"

Pour pouvoir compiler un schéma XSD, vous devez avoir le SDK Java d’installer. L’exécutable xjc.exe doit se trouver dans le répertoire bin du SDK.

Pour compiler le schéma et générer les classes Java adéquates, voici la ligne de commande à utiliser :

xjc –p <espace de nom> <fichier XSD>

Comme nous pouvons le voir, XJC à générer deux classes : Produits.java et ObjectFactory.java. Maintenant que les classes sont générées, voyons comment nous pouvons les utiliser dans notre application pour pouvoir parser ou générer un XML conforme à notre schéma XSD et donc être capable d’échanger de manière fiable avec toute autre application utilisant une autre technologie.

Le code suivant génère le XML adéquate :

ObjectFactory factory = new ObjectFactory();
Produits commande = factory.createProduits();
        
Produits.Produit produit1 = factory.createProduitsProduit();
produit1.setNom("Interoperabilité à tout prix");
produit1.setDescription("Un très bon livre pour mieux comprendre l'interopérabilité");
produit1.setPrix(30.00f);
commande.addProduit(produit1);

Produits.Produit produit2 = factory.createProduitsProduit();
produit2.setNom("Interoperabilite pour les nuls");
produit2.setDescription("Un très bon livre pour commencer son apprentissage en douceur de l'interoperabilite");
produit2.setPrix(20.00f);
commande.addProduit(produit2);

JAXBContext jaxbContext = JAXBContext.newInstance("jaxb");
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
   new Boolean(true));
marshaller.marshal(commande,
   new FileOutputStream("commande.xml"));

Génération des classes avec .NET

Le SDK .NET possède un outil très utile nommé XSD.exe qu’il vous suffira d’appeler avec la ligne de commande suivante pour générer les classes se conformant à un schéma XML de type XSD :

xsd.exe /classes <nom du schéma XSD>

Cette commande vous générera une classe du nom de votre schéma XSD :

Echanger entre les plateformes

Maintenant que nous avons d’un côté une application Java qui permet de générer du XML conforme au schéma XML et une autre en .NET qui sait parser celui-ci, nous allons simplement les faire communiquer via ce procédé de sérialisation XML. Sans changer beaucoup le code précédent, nous pouvons lire les objets sérialisés par l’application Java au travers de l’application .NET :

Console.WriteLine("Debut de la deserialisation ...");

Produits produits = null;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Produits));
using (Stream fs = new FileStream("commande.xml", FileMode.Open))
{
produits = (Produits)xmlSerializer.Deserialize(fs);
}

Console.WriteLine(String.Format("La commande a ete deserialise : {0}", produits));
Console.ReadLine();

Pour des raisons de simplicité le média d’échange entre l’application .NET et l’application Java est un fichier. Sachez que cet exemple fonctionne également très bien via un réseau ou une base de données.

L’intérêt d’utiliser un schéma XML est de garantir une homogénéité des données quelque soit les plateformes, les technologies et la méthode de développement des applications. Cette partie sur la sérialisation et l’utilisation d’un schéma XSD comme garant de la transaction d’échange est évidemment une introduction à la prochaine partie : les web services.

Les web services

Selon la définition du W3C – organisme de création et de maintenance des spécifications des Web Services – un web service est définit comme ‘un système de logiciel conçu pour supporter une interaction interopérable de machine à machine au travers d’un réseau’. Sans expliquer pour la énième fois l’intérêt et la nature des Web Service, voici juste quelques rappels rapides.

Au-delà de la définition du W3C, nous parlons souvent de Web Service comme d’une API web  qui peut-être accéder au travers d’un réseau, en général Internet, et qui exécute des services à distance sur une machine dédiée. Dans le cadre de cet article, je garderais cette définition puisque nous allons parler l’interopérabilité de deux plateformes et de leur librairie respective.

Les Web Service utilisent HTTP pour véhiculer les données, les messages SOAP pour encapsuler les données et le XML pour les structurer. Dans le monde des Web Services vous entendrez aussi parler de WSDL, notre fameux contrat d’échange, de UDDI pour la découverte des services dans différentes versions.

Afin de garantir une fiabilité des échanges entre les différentes implémentations, et de garantir donc l’interopérabilité des produits, les acteurs se sont regroupés en une organisation nommé WS-I (Web Service Interoperability) afin de définir une « sur-spécification » découpée en profile permettant de définir la version précise de chaque protocole ou standard à utiliser.

Afin d’étendre les capacités actuelles des Web Services, de nouvelles spécifications ont fait leur apparition dans ce que l’on appel WS-* (‘WS Start’) tel que WS-Security qui défini la façon de d’utiliser le XML Signature et le XML Encryption dans un message SOAP, WS-Reliability qui défini la fiabilité des échanges, WS-Addressing, WS-Transaction, etc

Remarque :Evidemment comme le nombre de couches, de validations et de complexité que les différentes spécifications apportent, il est évident que l’utilisation de Web Service est beaucoup plus lourde que l’utilisation de message à base de sérialisation XML.

Le projet WSIT

WSIT (Web Service Interoperability Technologies)  représente l’implémentation de référence de Sun de la brique interopérable de son serveur d’application Glassfish. Le projet Tango en particulier contribue à WSIT en permettant l’interopérabilité entre la plateforme Java et la plateforme de Microsoft Windows Communication Foundation.

Windows Communication Foundation

La plateforme de communication de Microsoft arrivée avec la sorite .NET 3 se nomme Windows Communication Foundation (WCF). Cette plateforme permet aux développeurs de réaliser des solutions orientées service en toute simplicité. WCF utilise notamment les attributs pour décorer les méthodes et les classes afin de spécifier leur rôle dans le service web.

Echange entre WSIT et WCF

Pour la démonstration de cet article nous allons nous placer dans un contexte ou un serveur d’application JEE fournit le Web Service et un client .NET vient le consommer.

Côté serveur avec Java

Dans un premier temps, nous allons créer le Web Service réduit à sa plus simple expression dans notre cas (pas d’authentification, de mécanisme de fiabilité, etc). Pour cela, nous avons utiliser NetBeans 6.0.1 et son modèle de projet de Web Service de calculatrice. Le code généré est le suivant :

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService()
public class CalculatorWS {

    @WebMethod(operationName = "add")
    public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
        return i + j;
    }
}

Déployez le projet dans le serveur en effectuant un clic droit sur le projet, puis copiez l’adresse de déploiement qui devrait être similaire à celle-ci : https://localhost:8080/CalculatorApp/CalculatorWSService .

Côté client avec WCF

Nous allons utiliser Visual Studio 2008 afin de générer les classes proxy pour le client du Web Service. Pour ce faire, créez un nouveau projet et ajouter une référence de service à votre projet avec l’adresse du WSDL du web service Java (n’oubliez pas le ?wsdl en fin d’URL) : https://localhost:8080/CalculatorApp/CalculatorWSService ?wsdl

Une fois que le service est référencé, vous pouvez utiliser les classes Proxy générées pour consommer avec WCF le service web créé :

CalculatorWS.CalculatorWS calcWSClient = new CalculatorWS.CalculatorWSClient();
            CalculatorWS.addRequest request = new CalculatorWS.addRequest(10, 100);
            Console.WriteLine(calcWSClient.add(request).@return);

Exécutez le code pour voir s’afficher le résultat de l’addition 10 + 100 :

Cet exemple se veut simple en n’utilisant aucune les fonctions avancées des Web Service, mais sachez que la plupart des fonctionnalités avancées montrent une interopérabilité assez avancée dans le domaine.

Le webcast suivant : https://www.microsoft.com/france/vision/WebcastMsdn.aspx?EID=024fb28a-9dab-4e1a-99a3-45cabbb00267 présenté par Stéphane Goudeau (Microsoft France) et Alexis Moussine-Pouchkine (Sun France) vous présentera des cas d’interopérabilité sur les spécifications avancées des Web Service.

Dans le chapitre précédent, nous utilisions un schéma XML de type XSD pour valider la structure XML des messages échangées entre les applications. Dans le cas d’un web service, il y a de nombreuses autres spécificités qui nécessitent une validation non pas seulement de la structure du message XML mais également de l’ensemble des détails de la communication (le point d’accès, les actions possibles, …)

Conclusion

L’interopérabilité se situe à plusieurs niveaux et pour différents besoins dans une entreprise ou une solution. Ici, nous n’avons qu’effleuré le sujet de l’interopérabilité en ne nous intéressant qu’à la communication entre la plateforme Java et .NET au niveau des messages XML sérialisé et des Web Service. Les engagements de Microsoft envers l’interopérabilité et les dernières initiatives tendent à montrer que l’éditeur à amorcer un véritable changement dans son comportement et qu’il est bien décidé à ouvrir la voie de l’interopérabilité vers les autres technologies.

Références

 

Haut de pageHaut de page