IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Format d'échange (XML, JSON...) Java Discussion :

analyse d'un flux reseau a la volee [SAX]


Sujet :

Format d'échange (XML, JSON...) Java

  1. #1
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut analyse d'un flux reseau a la volee
    Bonjour,

    voila mon probleme ... je veux faire communiquer deux applis entre elles en utilisant le xml... Pour ca, j'utilise SAX qui me paraissait le plus approprie et simple a utiliser.

    Pour l'instant, je code le serveur... je le teste avec telnet pour voir s'il fonctionne bien. Le seul probleme, c'est que l'analyse de flux xml s'effectue uniquement lorsque la connexion se ferme, pas avant... C'est un peu contraignant car pour faire dialoguer deux applis, l'interet etait de le faire en direct...

    Est ce que quelqu'un a deja utilise SAX pour faire dialoguer deux applis et a-t-il rencontre le meme genre de probleme ? Est-il possible de faire l'analyse reellement a la volee, ie, que la connexion ne soit pas termine ?

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    346
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 346
    Points : 439
    Points
    439
    Par défaut
    Je ne pense pas qu'il s'agisse à proprement parler d'un problème XML. Il me semble (car il y a un moment que je n'ai pas fait du client serveur bas niveau) qu'il faut "flusher" (désolé pour l'anglicisme) le flux pour envoyer les données ainsi si tu utilises un PrintWriter pw :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pw.println("chaîne envoyée");
    pw.flush();

  3. #3
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Pour l'instant, j'utilise telnet ... et il fait normalement un flush a chaque retour chariot... Je m'etais deja dis que ca devait venir de la donc j'ai tester en lisant octet par octet le flux renvoyer par telnet ... et aucun probleme, je peux lire sans probleme ce qui est envoye. Et effectivement, le flush s'effectue apres le retour chariot...

  4. #4
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Je viens de me faire un petit client java rapide pour tester a nouveau mon server ... il est extrement simple ... j'ouvre un socket vers le serveur, et j'envoie des donnees en xml ... du cote serveur, elles sont analysees lorsque la connexion est ferme ...

    NB : j'ai bien mis les flush apres chaque envoie

  5. #5
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Est ce que ca viendrait pas du parser que j'utiliser ? J'utilise celui de sun ? Est que si j'utilise xerces ou un autre, ca ne reglerais pas mon probleme ?

  6. #6
    Nouveau membre du Club
    Inscrit en
    Janvier 2005
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    pour info, quel est le type de flux que tu donne à ton parser sax ?

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    346
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 346
    Points : 439
    Points
    439
    Par défaut
    J'ai fait deux petites classes pour simuler un modèle client serveur très simple. Malheureusement ça ne marchait pas et pourquoi ? C'est relativement simple je faisais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pw.print("ma chaîne");
    au lieu d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pw.println("ma chaîne");
    La chaîne que je voulais envoyée n'avait pas le caractère de fin de ligne, peut-être as-tu le même problème sur ton serveur.
    Je ne pense pas que le problème vienne de l'api SAX.

  8. #8
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par laurenzo
    quel est le type de flux que tu donne à ton parser sax ?
    Je lui donne directement le InputStream du socket...

    Voila comment je cree mon parseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser saxParser = factory.newSAXParser();
    ServerSocket s = new ServerSocket(1234) ;
    Socket client = s.accept() ;
    saxParser.parse(client.getInputStream(), MyHandler() );
    nicolas581 : J'ai fais un client/serveur tout simple pour tester ... aucun probleme, il recoit bien tout apres chaque flush ... pas de probleme...

  9. #9
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    346
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 346
    Points : 439
    Points
    439
    Par défaut
    Le bout de code que j'ai pour analyser du Xml avec SAX :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setValidating(true);
    SAXParser saxParser = factory.newSAXParser();
    XMLReader reader = saxParser.getXMLReader();
    reader.setContentHandler(handler);
    reader.setErrorHandler(handler);   
    reader.parse(is);
    où is est un InputStream.
    Côté serveur, arrives-tu à analyser ton Xml ? Comment fais-tu tes écritures dans ta socket ?

  10. #10
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Bon, je viens d'adapter ton code a pour analyser xml avec SAX ... j'ai exactement le meme probleme ... le xml est bien analyse mais seulement lorsque la connexion se ferme...

    Citation Envoyé par nicolas581
    Comment fais-tu tes écritures dans ta socket ?
    A la base, je n'ecrivais pas dans ma socket car j'utilisais telnet ... je rentrais le xml a la main et il etait envoye au serveur ...

    Ensuite, pour voir si le probleme ne venait pas de telnet, j'ai creer mon client en java ... voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    String tab[] = new String[7] ;
    	tab[0]= "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" ;
    	tab[1]= "<session>" ;
    	tab[2]= "<login pseudo=\"Ben\"></login>" ;
    	tab[3]= "<message>Hello</message>" ;
    	tab[4]= "<message>Comment ca va?</message>" ;
    	tab[5]= "<message>Moi, ca va bien</message>" ;
    	tab[6]= "</session>" ;
     
    	try{
    	    Socket s = new Socket("localhost",1234) ;
    	    DataOutputStream out = new  DataOutputStream(s.getOutputStream());
     
     
    	    for ( int i = 0 ; i < 7 ; i++ ){
    		System.out.println(tab[i]) ;
    		out.writeBytes(tab[i]) ;
    		out.flush() ;
    		Thread.sleep(1500) ;
    	    }
    	}				      
    	catch(InterruptedException e){
    	    System.out.println("Sleep interrompu");
    	}
    	catch(IOException e){
    	    System.out.println("Connexion perdue");
    	}
    mais bon, je ne pense pas que le probleme vienne du client car j'ai le meme probleme quelquesoit le client ... de plus telnet est quand meme un client universel, non ?

  11. #11
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    346
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 346
    Points : 439
    Points
    439
    Par défaut
    Je voulais parler de l'écriture dans les sockets côté serveur, car je ne pense pas que le problème vienne du client, je ne mettrais pas en cause telnet quand même.
    J'espère que tu as accès au serveur sinon t'es mal barré.

  12. #12
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    bien sur que j'ai acces au serveur car je suis en train de le developper ... et c'est justement la que ca coince ....

    Pour l'instant, cote serveur je n'ecris pas dans le socket ... j'en suis vraiment a la base ... je voulais me connecter a mon serveur, lui envoyer du xml et voir comment il l'analysait ...

    Donc pour resumer, j'ai tres peu de classe au niveau de mon serveur ... un Handler et grossomodo le code que j'ai poste plus haut pour creer mon parseur... ( tres simple pour le moment ).

  13. #13
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    346
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 346
    Points : 439
    Points
    439
    Par défaut
    J'ai la solution de ton problème mais je n'ai pas le temps j'essaye d'écrire ce soir ou demain car là je dois partir.
    @+

  14. #14
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    346
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 346
    Points : 439
    Points
    439
    Par défaut
    Désolé pour le code un peu long, testé sous j2se 1.5, mais je n'utilise pas de fonctionnalités avancées. Le client lit un fichier xml ligne par ligne l'envoie au serveur, celui-là analyse le flux xml et effectue un affichage simple.

    Serveur.java : Pour une utilisation normale penser au mutli-thread car ici un seul client peut se connecter à la fois. Le serveur reçoit un fichier dans une socket et analyse le fichier xml.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import java.io.*;
    import java.net.*;
    import org.xml.sax.*;
     
    public class Serveur {
     
        public static void main (String args[]) {
    	BufferedReader br;
    	PrintWriter pw;
    	String ligne;
    	try {
    	    ServerSocket contact = new ServerSocket(8003);
    	    System.out.println("Serveur en écoute sur le port 8003");
    	    while (true) { 
    		Socket client = contact.accept();
    		System.out.println("Connection avec " + client);
    		br = new BufferedReader(new InputStreamReader(client.getInputStream()));
    		pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true);
    		InputSource is = new InputSource(new InputStreamReader(client.getInputStream()));
    		XmlParser xp = new XmlParser(is);
    		br.close();
    		client.close();
    	    }
    	}
    	catch(Exception e) {
    	    System.err.println(e);
    	    e.printStackTrace();
    	}
        }
    }
    Client.java : Lit le fichier xml et l'envoie dans une socket.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import java.io.*;
    import java.net.*;
     
    public class Client {
     
       public static void main (String args[]) {
           String ligne;
           BufferedReader br, in;
           PrintWriter pw;
           try {
    	   Socket socket = new Socket("127.0.0.1", 8003);
    	   // lecture de la socket
    	   br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
    	   // ecriture de la socket
    	   pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
    	   // lecture sur entrée standard
    	   in = new BufferedReader(new InputStreamReader(System.in));
    	   System.out.println("Connection établie : " +
    			      socket.getInetAddress() + " port : " + socket.getPort() + " port local : " + socket.getLocalPort());
    	   // envoie du fichier
    	   BufferedReader br2 = new BufferedReader(new FileReader("fichier.xml"));
    	   while ((ligne = br2.readLine()) != null) {
    	       pw.println(ligne);
    	       pw.flush(); // pour éviter le flush ouvrir le pw avec true en 2 paramètre.
    	       System.out.println(ligne);
    	   }
    	   br2.close();
    	   socket.close();
           }
           catch(Exception e) {
    	   System.err.println("Problème socket !!!  " +e);
           }
       }
    }
    AnalyseSax.java : analyse le flux xml et effectue des affichages simples.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import javax.xml.parsers.*;
    import org.xml.sax.helpers.DefaultHandler;
    import org.xml.sax.*;
    import java.io.*;
     
     
    public class AnalyseSax extends DefaultHandler {
     
        public void startElement (String namespaceURI, String localName,
    			      String qName, Attributes atts) {
     
    	System.out.println("element : "+namespaceURI+" - "+localName+" - "+qName);
    	for (int i=0; i<atts.getLength(); i++)
    	    System.out.println("  attributs : "+atts.getURI(i)+" - "+
    			       atts.getLocalName(i)+" - "+
    			       atts.getQName(i)+" = "+
    			       atts.getValue(i));
        }
     
        public void characters (char[] ch, int debut, int l) {
    	System.out.print("  texte : ");
    	for (int i=0; i<l; i++)
    	    System.out.print(ch[debut+i]);
    	System.out.println();
        }
     
        public void warning (SAXParseException e) {
    	System.out.println("WARNING : " + e);
        }
     
        public void error (SAXParseException e) {
    	System.out.println("ERROR : " + e);
        }
    }
    XmlParser : mise en place du parser à partir d'un InputSource.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import javax.xml.parsers.*;
    import org.xml.sax.helpers.DefaultHandler;
    import org.xml.sax.*;
    import java.io.*;
     
    public class XmlParser { 
     
        AnalyseSax handler;
        public XmlParser(InputSource is) {
    	handler = new AnalyseSax();
    	try{
    	    SAXParserFactory factory = SAXParserFactory.newInstance();
    	    SAXParser saxParser = factory.newSAXParser();
    	    XMLReader reader = saxParser.getXMLReader();
    	    reader.setContentHandler(handler);
    	    reader.setErrorHandler(handler);
    	    reader.parse(is);
    	}
    	catch (Exception e){
    	    System.err.println("Pb de SAX");
    	    e.printStackTrace();
    	    System.exit(2);
    	}
        }
    }
    Merci pour ce bon exercice de révision des flux et du xml .

  15. #15
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Ok, je te remercie d'avoir pris du temps sur mon probleme ... je vais tester ta solution ...

  16. #16
    Nouveau membre du Club
    Inscrit en
    Janvier 2005
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    bonsoir,

    benratti, c coi la différence avec ton code stp pour comprendre ....
    merci

  17. #17
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par laurenzo
    c coi la différence avec ton code stp pour comprendre ....
    Pour l'instant j'ai pas encore une le temps de regarder precisement la difference entre mon code et celui poste par nicolas581 ( cf l'heure de mon post ) ... je regarde dans la journee et je t'explique.

  18. #18
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Je viens de jeter un coup d'oeil au code ... visiblement, la seule difference importante est ce que l'on donne au parseur ... moi je donnais directement l'InputStream recupere a partir du socket client, et lui il construit un InputStreamReader puis un InputSource...

    Par contre, si quelqu'un peut m'expliquer pourquoi ca marche dans un cas et pas dans l'autre, je suis preneur.

  19. #19
    Nouveau membre du Club
    Inscrit en
    Janvier 2005
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    En fait ton code fonctionne mais il y a un buffer qui ne se vide pas aussi vite que si il y a un reader entre l'inputsource et l'inputStream du socket.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    public class Client {
     
      public static void main(String args[]) {
        String ligne;
        PrintWriter pw;
        try {
          Socket socket = new Socket("127.0.0.1", 8003);
          pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()) , true);
          System.out.println("Connection établie : " + socket.getInetAddress() + " port : " + socket.getPort() + " port local : " + socket.getLocalPort());
          BufferedReader readerFichierXML = new BufferedReader(new FileReader("fichier.xml"));
          int compteurTaille = 0;
          while ( (ligne = readerFichierXML.readLine()) != null) {
            pw.println(ligne);
            Thread.sleep(50);
            compteurTaille=compteurTaille+ligne.length();
            System.err.println(compteurTaille/1024);
          }
          readerFichierXML.close();
          socket.close();
          System.err.println("FIN DE TRAITEMENT");
        }
        catch (Exception e) {
          System.err.println("Problème socket !!!  " + e);
        }
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class Serveur {
      public static void main(String args[]) {
          try {
            ServerSocket contact = new ServerSocket(8003);
            System.out.println("Serveur en écoute sur le port 8003");
            while (true) {
              Socket client = contact.accept();
              System.out.println("Connection avec " + client);
              // V benratti
              InputSource is = new InputSource(client.getInputStream());
              // V nicolas581
    //          InputSource is = new InputSource(new InputStreamReader(client.getInputStream()));
              new XmlParser(is);
              client.close();
            }
          }
          catch (Exception e) {
            System.err.println(e);
            e.printStackTrace();
          }
      }
    }
    Fait le test avec un gros fichier XML pour que cela apparaisse.
    Dans mon test, il faut environ 7 / 8 ko pour que le buffer se vide.


    .

  20. #20
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Je te remercie des tes explications limpides... ca fait aussi plaisir de voir que mon code fonctionne ... mais pas avec mes attentes... je vais donc opter pour la solution de nicolas581...

    Merci a vous deux.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Analyse d'un flux XML
    Par kqman dans le forum Format d'échange (XML, JSON...)
    Réponses: 11
    Dernier message: 02/03/2010, 16h49
  2. capture de flux reseau
    Par MissK dans le forum RedHat / CentOS / Fedora
    Réponses: 1
    Dernier message: 20/08/2009, 11h48
  3. Gestion de flux - reseau
    Par MonkeyJLuffy dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 13/08/2008, 12h12
  4. probleme lors de l'analyse d'un flux xml sous asp
    Par jlassira dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 05/07/2005, 14h01
  5. [SAX] analyser directement un flux
    Par benratti dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 09/12/2004, 14h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo