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

Entrée/Sortie Java Discussion :

afficher un objet reçu via socket java


Sujet :

Entrée/Sortie Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Août 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Août 2019
    Messages : 9
    Points : 11
    Points
    11
    Par défaut afficher un objet reçu via socket java
    Salut à tous!
    Je viens solliciter votre aide n'étant pas très certain que c'est au bon endroit où je pose mon message...
    Au fait, je développe une application client-serveur, utilisant éclipse comme IDE. Mes deux applications marchent bien n'étant pas exportées.
    Le problème est qu'ayant exporté mon application client en jar exécutable, celle-ci ne parvient plus afficher les objets de type tableau (qu'elle affichait très bien avant exportation) qu'elle reçoit via le réseau.
    par ailleurs, elle reçoit et affiche sans souci les chaines de caractère qu'elle reçoit de l'application serveur. Je ne sais comment m'y prendre, qu'il plaise à quelqu'un de me débloquer

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Avec du code on comprendrait plus facilement que quoi tu parles.

    Citation Envoyé par VitalK Voir le message
    ne parvient plus afficher les objets de type tableau (qu'elle affichait très bien avant exportation)
    C'est-à-dire ? Que se passe-t-il ? Il y a une exception ? Et qu'est-ce tu appelles exactement des "objets de type tableau" ? Comment se fait le transfert exactement ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Août 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Août 2019
    Messages : 9
    Points : 11
    Points
    11
    Par défaut
    salut, j'aurais du penser à mettre du code. Au fait le client envoie une requête au serveur, celui-ci sérialise le résultat dans un JTable puis le déserialise, et enfin l'envoi au client qui ne fait qui ne fait qu'un casting (en JTable) de l'objet reçu puis l'affiche dans un JPanel. voici mes codes:

    côté serveur:
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    	//Classe réception des messages et des requêtes
     
    	class ReceptionMessage extends Thread{
    		ExecutionRequete exereq;
    		Communication commu;
    		ObjectInputStream ois;
    		ObjectOutputStream oos;
    		Object str=new Object();
    		String messageRecu="",st="";
    		int numeroClient;
    		boolean message=false, requete=false;
     
    		ReceptionMessage(Communication com, int numeroclient){
    			this.commu=com;
    			this.numeroClient=numeroclient;
    			this.ois=commu.ois;
    			this.oos=commu.oos;
    			compteurClient++;
    			setNomFichierResultat("Client"+compteurClient);
    		}
     
    		public void run() {
    			while(true){
    				try {
    					try {
    						str=(Object)ois.readObject();
    						if(str.toString().startsWith("\tvitdmsg")){
    							message=true;
    							requete=false;
    						}
    						if(str.toString().startsWith("\tvitdreq")){
    							message=false;
    							requete=true;
    						}
    						if(message){//Construction du message
    							st=str.toString()+"\n";
    							messageRecu+=st;							
    						}
    						if(str.toString().endsWith("\tvitfmsg")){//si le message est entièrement reçu
    							messageRecu=messageRecu.substring(8, messageRecu.length()-8);
    							panChat.add(new BlocChat("Client-"+numeroClient,messageRecu));
    							panChat.revalidate();
    							messageRecu="";
    							message=false;
    						}
    						if(requete){//Si c'est une requête, on la construit
     
    							if(accesBDD){
    								st=str.toString();							
    								messageRecu=st.substring(8, st.length());	
    								exereq=new ExecutionRequete(messageRecu);
    								exereq.start();
    								while(!exereq.resSerialPret)System.out.println("Téléchargement en cours ...");
    								System.out.println("Téléchargement terminé!");
    						//		afficherResultatRequete(getNomFichierResultat());
    								oos.writeObject(tabResSerial);
    								oos.flush();
     
    								messageRecu="";
    								requete=false;
    								exereq.resSerialPret=false;
    							}
    						}
     
    					} catch (java.net.SocketException e) {
    						System.out.println("Auto-déconnexion brusque du client "+numeroClient);
    						conteneurBloc.remove(tabBlocClient[numeroClient-1]);
    						panBtnClient.revalidate();
    						ois.close();
     
    						break;
    					}
     
    				} catch (ClassNotFoundException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
     
    		}		
    	}
    classe qui traite les requêtes reçues

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    	//Classe d'exécution des requêtes
     
    	class ExecutionRequete extends Thread{
    		private String requete="";		
    		private ResultSet resultat;
    		ObjectOutputStream oosSerial;
     
    		private int ligne=0, colonne=0;
    		private JTable tableResultat;
    		boolean resSerialPret=false;
     
    		ExecutionRequete(String req){
    			this.requete=req;
     
    		}
    		public synchronized void run(){
     
    			try {				
    				try {
    					resultat=stm.executeQuery(requete);
    					while(resultat.next())ligne++; //on renseigne le nombre de lignes
    					resultat=stm.executeQuery(requete);
    					genererResultat(resultat);	
     
    				} catch (com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException e) {
    					System.out.println("Connexion à la base des données non admise");
    				}
    			//	afficherResultat(resultat);
    			} catch (SQLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}			
    		}
    		//Méthode de construction du tableau des résultats
    		protected void genererResultat(ResultSet result){
     
    			String[] tabTitre;
    			String[][] tabDonnees;
     
     
    			try {
    				colonne=result.getMetaData().getColumnCount();//on renseigne le nombre de colonnes
    				System.out.println("Nombre de colonnes: "+colonne);
    				tabTitre=new String[colonne];
    				for(int i=1;i<=colonne;i++){//Remplissage du tableau des titres
    					tabTitre[i-1]=result.getMetaData().getColumnName(i);
    				}				
    				System.out.println("nombre de lignes trouvé: "+ligne);				
    				tabDonnees=new String[ligne][colonne];
    				//Remplissage des données
    				int l=0;
    				while(result.next()){
    					for(int k=1;k<=colonne;k++){			
    						tabDonnees[l][k-1]=result.getString(k);						
    					}
    					l++;
    				}
    				//remplissage du JTable
    				this.tableResultat=new JTable(tabDonnees,tabTitre);
    				//Sérialisation et désérialisation
    				try {
    					this.oosSerial=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(new File("ResReq/"+nomFichierResultat))));
    					oosSerial.writeObject(tableResultat);
    					oosSerial.close();	
    					ObjectInputStream oisSerial=new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("ResReq/"+nomFichierResultat))));
    					try {
    						tabResSerial=(JTable)oisSerial.readObject();
    						resSerialPret=true;
    					} catch (ClassNotFoundException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
     
    			} catch (SQLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
     
    		}		
     
    		// Méthode d'affichage du tableau des résultats
    		void afficherResultatConsole(ResultSet result){
     
    			try {
    				while(result.next()){
    					for(int i=1;i<=result.getMetaData().getColumnCount();i++){
    						System.out.print(result.getString(i)+"\t|");
    					}			
    					System.out.println("\n-----------------------------------------");
    				}
    			} catch (SQLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    coté client
    Classe de réception d'objets et chaines de caractères
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    class ReceptionMessage extends Thread{
     
    		Object str=new Object(),objetRecu=new Object();
    		String messageRecu="",st="";
    		boolean message=false, objet=false;
     
    		public void run(){
    			while(true){
    				try {
    					try {
    						try {
    							str=(Object)ois.readObject();
    						} catch (java.net.SocketException e) {//Lorsque on ferme la fenêtre du serveur sans déconnexion des clients
    							System.out.println("Fermeture brusque du serveur");
    							ois.close();
    							break;
    						}
    					} catch (java.io.EOFException e) {//Déconnexion à partir du serveur						
    						labBienvenue.setText("Déconnexion à partir du serveur");
    						ois.close();
    						break;
    					}
    					try {//Portion de vérification du type
    						if(str.toString().startsWith("\tvitdmsg")){//vérification du type
    							message=true;//c'est un message
    							objet=false;//c'est le résultat d'une requête
    						}
    					} catch (NullPointerException e) {//C'est un objet
    						objet=true;
    					}
    					if(message){ //Si c'est un message, construction du message
    						st=str.toString()+"\n";
    						messageRecu+=st;
    					}
    					if(message==false)objet=true;
    					try {
    						if(str.toString().endsWith("\tvitfmsg")){//On affiche le message une fois reçu entièrement
    							messageRecu=messageRecu.substring(8, messageRecu.length()-8);
    							conteneurBloc.add(new BlocChatReception(messageRecu));
    							jspConteneurBloc.revalidate();
    							System.out.println("Réception du message:"+str.toString());
    							messageRecu="";
    							message=false;
     
    						}
    					} catch (NullPointerException e) {
    						objet=true;
    					}					
    					if(objet){//si c'est un objet; lecture de l'objet
    						System.out.println("C'est un objet");//On fait aussi sa lecture
    						objet=false;
    						afficherResultat(str);
    						panCentral.revalidate();	
    					}
     
    				} catch (ClassNotFoundException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
     
    //Méthode qui affiche sérialise le tableau reçu et l'affiche. la sérialisation étant facultative
     
    		private void afficherResultat(Object tabres){
    			JTable tabResSerial=new JTable();
    			try {
    				ObjectOutputStream oosSerial=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(new File("ResReq"))));
    				oosSerial.writeObject(tabres);
    				oosSerial.close();
    				System.out.println("Fin de sérialisation");
    				ObjectInputStream oisSerial=new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("ResReq"))));
    				try {
    					tabResSerial=(JTable)oisSerial.readObject();
    					oisSerial.close();
    				} catch (ClassNotFoundException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			} catch (FileNotFoundException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			panResultat.removeAll();
    			panResultat.add(new JScrollPane(tabResSerial));
     
    			System.out.println("C'est fait!");
     
    		}
    	}
    et enfin la classe qui envoie les requêtes
    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
    	// Classe des types de requetes
    	class MesRequetesListener implements ActionListener{
    		String requete="";
    		public void actionPerformed(ActionEvent arg0) {
    			if(arg0.getSource().equals(btnRechNumPlaque)){
    				requete="\tvitdreqSELECT * FROM Eleve";//On donne une valeur à la requête
    				System.out.println(requete);
    			}
    			try {
    				try {
    					oos.writeObject(requete);
    					oos.flush();
    					requete="";
    				} catch (java.net.SocketException e) {//Lorsqu'on n'est pas connecté					
    					labBienvenue.setText("Vous n'êtes pas connecté");
    				}
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    Voilà, c'est fait. Comme annoncé dans mon premier message, les deux applications fonctionnent bien n'étant pas encore exportées. après exportation du client en jar exécutable aucun n'affichage de tableau, aucune erreur non plus... c'est dur de savoir par où commencer. Merci encore de bien vouloir m'assister

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par VitalK Voir le message
    c'est dur de savoir par où commencer
    A vrai dire, c'est pareil pour moi.
    J'ai envie d'écrire pour commencer "fouyaya.". Ensuite "Je ne vois aucune socket là-dedans". Ensuite "fouyaya!". Enfin je veux dire qu'il y a :

    1. du code inutilement compliqué
    2. d'autres choses qui ne vont pas


    Pour la partie "socket", sous-entendu transfert de ce que tu appelles "tableau", qui est un objet de classe JTable donc, à priori, qu'on voudrait transférer (sur le réseau) par sérialisation/désérialisation, difficile de répondre sans la partie socket.

    Ensuite :

    1. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      exereq=new ExecutionRequete(messageRecu);
      exereq.start();
      while(!exereq.resSerialPret)System.out.println("Téléchargement en cours ...");
      1. Pourquoi utiliser un autre thread si c'est pour "attendre" qu'il soit terminé pour continuer ?
      2. On n'utilise pas boucle while pour "attendre" qu'un thread soit terminé. En particulier en testant un booléen non volatile (il devrait l'être).
        On utilise join() par exemple, ou du wait()/notify(), ou un pattern "observer".

      Au passage :

    2. A quoi ça sert de sérialiser un objet dans un fichier pour le désérialiser immédiatement après dans la même séquence de code ?
      Si on le sérialise, c'est qu'il est forcément en mémoire. S'il est en mémoire, pourquoi le sérialiser puis le désérialiser : il est déjà là, en mémoire.
    3. Il y a un truc qui m'étonne, c'est que ça fonctionne dans l'IDE : dans la partie serveur on créé un fichier de chemin "ResReq/<quelque chose>", donc ResReq est forcément un dossier. Dans la partir client on lit un fichier de nom "ResReq". On ne peut pas lire un dossier comme si c'était un fichier. Ou alors, les deux programmes sont dans deux projets différents ?
    4. Tu fais la requête à la base deux fois ? Une fois pour compter les lignes et une fois pour construire le tableau de données !!!
      1. on peut utiliser un Vector (de Vector) pour créer une JTable. Ce qui n'oblige pas à connaître un nombre de lignes nécessaire à la création d'un tableau
      2. on peut utiliser une requête en mode TYPE_SCROLL* pour déplacer le curseur à la fin du ResultSet pour connaître le nombre de lignes et revenir au début pour consommer le ResultSet
      3. on peut faire un "select count".
    5. pourquoi transférer une JTable et pas simplement les données et c'est le client qui crée la JTable ?
    6. transférer des objets par le réseau, via la sérialisation/désérialisation peut poser différents problèmes. D'ailleurs cette possibilité pourrait bien être supprimée à l'avenir (possibilité d'injection de code). Maintenant, ne voyant pas ton code de socket, difficile d'en savoir plus sur cet aspect.
      Pourquoi ne pas faire un accès JDBC distant ? Et utiliser des PreparedStatement ? Parce qu'en plus, passer des requêtes en String par le réseau offre des possibilités d'injection SQL. Pour la partie chat, oui, pourquoi pas échanger des String via socket (pas la peine d'utiliser des Object(Input/Ouput/Stream.
      Si c'est dans le but d'expérimenter les sockets, à la limite, se cantoner à échanger des Strings structurées. Du Json par exemple.
      Après, si le but est d'expérimenter le partage d'objets sur le réseau, il y a aussi RMI.
    7. On doit éviter qu'un thread qui ne soit pas l'Event Dispatch Thread ne modifie l'UI Swing.

    8. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      if(message){ //Si c'est un message, construction du message
      						st=str.toString()+"\n";
      						messageRecu+=st;
      					}
      Tu construis messageRecu en concaténant différents messages reçus...
      Ensuite tu fais ça :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      if(str.toString().endsWith("\tvitfmsg")){//On affiche le message une fois reçu entièrement
      							messageRecu=messageRecu.substring(8, messageRecu.length()-8);
      je comprends bien que tu cherches à supprimer tes "balises" de début et de fin de message... mais c'est sur str, ces balises, pas sur messageRecu. Alors par conséquence comme le dernier message est concaténé à la fin de messageRecu, la balise de fin se trouve bien à la find de messageRecu, mais pas au début... sauf pour le premier message. Après tu grignotes petit à petit juste le début de la suite de messages concaténés.
    9. Tu ne fermes jamais vraiment correctement tes ressources, JDBC comme IO... utilise try-with-resource
    10. je n'approndi pas... il y a peut-être/sûrement d'autres soucis que je n'ai pas vus, mais pas assez de temps pour décortiquer ton "code"...


    Tu lances ton application en console ? Ou en double-cliquant sur le jar, ce qui pourrait te masquer les stacktraces... et te faire penser qu'il n'y a pas d'erreurs.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Août 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Août 2019
    Messages : 9
    Points : 11
    Points
    11
    Par défaut
    Merci Joel, ton analyse avec détail m'inspire beaucoup.
    En soi, la partie serveur et la partie client, c'est deux projets différents.
    Je suis parti du principe que ma seule classe de réception des messages (ReceptionMessage) doit faire un tri et découvrir le type de donnée (soit un message, soit une requête, soit un objet) entrant et ainsi à chaque type exécuter un traitement particulier. C'est pas tout à fait ingénieux, mais bon...https://www.developpez.net/forums/im...lies/toine.gif, c'est ce qui correspond à ce bout de 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    str=(Object)ois.readObject();
    						if(str.toString().startsWith("\tvitdmsg")){
    							message=true;
    							requete=false;
    						}
    						if(str.toString().startsWith("\tvitdreq")){
    							message=false;
    							requete=true;
    						}
    						if(message){//Construction du message
    							st=str.toString()+"\n";
    							messageRecu+=st;							
    						}
    						if(str.toString().endsWith("\tvitfmsg")){//si le message est entièrement reçu
    							messageRecu=messageRecu.substring(8, messageRecu.length()-8);
    							panChat.add(new BlocChat("Client-"+numeroClient,messageRecu));
    							panChat.revalidate();
    							messageRecu="";
    							message=false;
    						}
    						if(requete){//Si c'est une requête, on la construit
     
    							if(accesBDD){
    								st=str.toString();							
    								messageRecu=st.substring(8, st.length());	
    								exereq=new ExecutionRequete(messageRecu);
    								exereq.start();
    								while(!exereq.resSerialPret)System.out.println("Téléchargement en cours ...");
    								System.out.println("Téléchargement terminé!");
    						//		afficherResultatRequete(getNomFichierResultat());
    								oos.writeObject(tabResSerial);
    								oos.flush();
     
    								messageRecu="";
    								requete=false;
    								exereq.resSerialPret=false;
    							}
    						}
    Ensuite t'as tout à fait raison que la classe d'exécution des requêtes n'a pas raison d'être un Thread (D'où une partie du code qui en découle est inutile).
    Cependant quant à la sérialisation et désérialisation c'est afin de contourner la difficulté d'envoyer directement au client les données d'un resultSet d'autant plus que ce dernier est lié à la connexion en cours avec la BDD. Certes pas génial mais j'ai trouvé qu'envoyer des objets désérialisés est tant soit peu une solution palliative (et surtout que je peux les relire même sans être connecté). De plus en fouillant sur le net, j'ai pu lire que cela permet de libérer l'accès à d'autres clients qui interrogent la BDD en même temps...

    Du côté client ResReq n'est pas dossier(ou pas un répertoire), c'est juste le fichier sérialisé.

    Comme précisé ci-haut, c'est deux projets distincts: donc un serveur et un client. le serveur a la capacité de gérer plusieurs clients. Je lance les deux projets en mode console (sur eclipse)et ça marche correctement sans erreurs. Mais lorsque j'exporte le client en jar exécutable, le chat entre clients et serveur se déroule comme prévu (fonctionne correctement ), mais le tableau (résultat sérialisé) comme réponse à chaque requête des clients ne s'affiche pas. et c'est ce qui me dépasse.
    Je prends en considération vos suggestions pour faire un système simple et efficace, cependant en considérant que ce que j'ai fait jusqu'ici marche sur eclipse pouvez-vous trouver ce qui cloche après export en jar exécutable ?

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par VitalK Voir le message
    Merci Joel, ton analyse avec détail m'inspire beaucoup.
    En soi, la partie serveur et la partie client, c'est deux projets différents.
    Je suis parti du principe que ma seule classe de réception des messages (ReceptionMessage) doit faire un tri et découvrir le type de donnée (soit un message, soit une requête, soit un objet) entrant et ainsi à chaque type exécuter un traitement particulier. C'est pas tout à fait ingénieux, mais bon...
    Ce n'est pas ça qui me dérange : tu peux avoir plusieurs types de messages et utiliser le moyen qui te plait pour les distinguer. Mais pour le traitement, c'est mieux de déléguer à des méthodes séparées et dédiées, plutôt que d'avoir plusieurs booléens dont si l'un est true, l'autre doit être false, etc. En plus, le fait d'avoir des codes séparés facilite l'analyse : on ne s'intéresse qu'au code qui ne fonctionne pas sans avoir à démêler au milieu de plusieurs traitements les parties qui concernent ce qui ne fonctionne pas. Cela peut également avoir le mérite de supprimer les tentations de contamination des différentes parties entre-elles par des variables annexes communes. Isolation est le maître mot. Du coup, en cas de multiplication des types de messages, il est aisé de déporter le code dans des classes à part, d'introduire un système de lookup, et de traiter par une simple boucle la sélection du traitement adéquate au lieu d'avoir des ifs/else if/else if ou autres switch. Les cas d'exception peuvent être traités par fallback éventuellement. Mais bon, ça c'est pour la théorie. En ce qui concerne le problème qui nous occupe, le but est surtout d'éviter que j'ai à analyser de code qui n'a rien à avoir avec le problème.

    Citation Envoyé par VitalK Voir le message
    Ensuite t'as tout à fait raison que la classe d'exécution des requêtes n'a pas raison d'être un Thread (D'où une partie du code qui en découle est inutile).
    Cependant quant à la sérialisation et désérialisation c'est afin de contourner la difficulté d'envoyer directement au client les données d'un resultSet d'autant plus que ce dernier est lié à la connexion en cours avec la BDD.
    Ce n'est pas mauvais en soi que le serveur se charge de l'accès JDBC et que le client accède à la base par l'intermédiaire de services, mais on perd totalement le bénéfice de la chose lorsque le client envoie sur le réseau une requête SQL en chaîne de caractères ! Il n'y a pas plus de difficultés de sérialiser des données dans du xml ou du json, sans passer par la sérialisation d'instance de classe que de le faire par celle-ci. Cela rend juste le format indépendant de la notion de classe et de version de classe. C'est le principe courant des services REST.
    Ce n'est pas la source qui change quoique ce soit à cette difficulté. Evidemement, il ne s'agit pas d'envoyer le ResultSet sur le réseau : autant utiliser JDBC dans ce cas.

    Citation Envoyé par VitalK Voir le message
    Certes pas génial mais j'ai trouvé qu'envoyer des objets désérialisés est tant soit peu une solution palliative
    Cela n'empêche pas qu'il n'y a aucun intérêt côté serveur de sérialiser dans un fichier puis de désérialiser le fichier. Envoyer l'objet sérialisé sur le réseau ne nécessite pas de passer par un fichier. Eventuellement le fichier pourrait servir de cache, mais la désérialisation du fichier n'a aucun intérêt.

    Citation Envoyé par VitalK Voir le message
    (et surtout que je peux les relire même sans être connecté).
    Cela pourrait être le seul argument qui justifierait d'utiliser de la sérialisation/désérialisation. Mais
    1. pour moi la serialisation/deserialisation se limite depuis longtemps à du transfert réseau, et on sait depuis quelques temps que cette option est également problématique (injection de code, j'en ai déjà parlé). A du stockage non pérenne éventuellement (non pérenne, limité à un runtime donc, ou une série de runtime lors d'une session, ne serait-ce à cause des versions de classe).
    2. on n'est pas obligé de sérialiser des objets haut niveau comme des composants d'UI. On peut sérialiser une structure de données.



    Citation Envoyé par VitalK Voir le message
    De plus en fouillant sur le net, j'ai pu lire que cela permet de libérer l'accès à d'autres clients qui interrogent la BDD en même temps...
    Cela n'a aucun rapport, ni de près, ni de loin. On peut avoir autant de clients qu'on veut en même temps, sans avoir aucune sérialisation et inversement, on peut avoir un système fondé sur de la sérialisation/désérialisation qui mettent les accès utilisateurs dans une queue mono-utilisateur.

    Citation Envoyé par VitalK Voir le message
    Du côté client ResReq n'est pas dossier(ou pas un répertoire), c'est juste le fichier sérialisé.
    oui enfin tu as :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.oosSerial=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(new File("ResReq/"+nomFichierResultat))));
    Ici c'est forcément un dossier. S'il existe déjà un fichier de ce nom, le code ci-dessus lèvera une exception. Ou l'exception sera levée à la création du fichier, si le dossier a été créé auparavant.
    Mais en effet, si les deux applications sont lancées dans des projets différents, le problème ne peut avoir lieu lors de l'exécution dans l'IDE. En revanche, hors de l'IDE, à partir des jar exportés, les jar devront être lancés dans des dossiers de travail différents, pour éviter la collision.

    Citation Envoyé par VitalK Voir le message
    Je prends en considération vos suggestions pour faire un système simple et efficace, cependant en considérant que ce que j'ai fait jusqu'ici marche sur eclipse pouvez-vous trouver ce qui cloche après export en jar exécutable ?
    Bah, j'ai déjà dit que sans la partie socket du code, je ne peux pas déterminer quel(s) problème(s) il peut y avoir sur la partie réseau du système.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Août 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Août 2019
    Messages : 9
    Points : 11
    Points
    11
    Par défaut
    Salut Joel,
    Au fait j'ai résolu le problème en faisant de ce jar exécutable un setup, et du coup après installation ça a marché; le client reçoit tableau et tout type de données comme il en était le cas sur eclipse. Je ne sais trop comment expliquer, mais je sais que le logiciel eclipse prend en charge la gestion de variables d'environnement de toutes les applications s'exécutant au travers lui; ce qui n'était pas le cas avec le jar exécutable... (il me semble qu'après installation le système d'exploitation a récupéré sa gestion).

    Mon souci était que mon code, et bien-sûr que tout mon système (client-serveur) fonctionne. Cependant ton analyse détaillée et objective sur les grandes lignes de mon code, me laisse entrain de revoir les codes de mes deux projets ligne après ligne, et pour cela grand merci Joel.
    A très bientôt pour un autre sujet...

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 07/07/2013, 20h26
  2. Communication Java - Silverlight via Socket
    Par Seb59118 dans le forum Silverlight
    Réponses: 4
    Dernier message: 02/12/2009, 17h53
  3. Transfert d'objet via sockets
    Par benjamin-mermoz dans le forum Windows Forms
    Réponses: 5
    Dernier message: 11/12/2008, 21h34
  4. Debutant Java afficher contenu objet
    Par jcaspar dans le forum Langage
    Réponses: 5
    Dernier message: 14/02/2007, 17h13
  5. Connexion via Socket JAVA
    Par jihene dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 08/06/2006, 18h50

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