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

Développement Web en Java Discussion :

Envoi d'un dossier zippé en HTTP


Sujet :

Développement Web en Java

  1. #1
    Membre actif
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2013
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 131
    Points : 203
    Points
    203
    Par défaut Envoi d'un dossier zippé en HTTP
    Bonjour tous le monde,

    je suis confronté à un souci que je n'arrive pas à élucider.
    Je souhaite envoyer via HTTP un dossier zipper (zipper avec les librairies standart de java). L'envoi se passe bien du coté client car le serveur recoit exactement le nombre d'octet envoyé qui correspond bien au poids du zip d'origine.
    Mon seul souci est que lorsque j'essaye d'ouvrir mon dossier ZIP qui contient bien tous les dossiers et fichiers voulus (avec leur poids respectifs valides), winrar ou meme windows me dise que le dossier est corrompu et donc impossible de l'ouvrir.
    Quelqu'un pourrait t'il m'éclaircir, voici mon code M%

    Code client :

    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
    static String callHttp(String surl, File f, String login, String pwd) throws Exception {
    		System.out.println("HttpListener.callHttp[" + surl + "//" + login + ":" + pwd + "]: ");
     
    		HttpURLConnection httpCon = null;
    		URL u = null;
    		StringBuffer res = new StringBuffer();
    		FileInputStream fis = null;
    		OutputStreamWriter out = null;
    		BufferedReader in = null;
    		try {
    			u = new URL(surl);
    			httpCon = (HttpURLConnection) u.openConnection();	
    			httpCon.setDoOutput(true);
    			httpCon.setDoInput(true);
    			httpCon.setRequestProperty("Content-Type", "application/zip");
     
    			byte[] bFile = new byte[(int) f.length()];
    			fis = new FileInputStream(f);
    			fis.read(bFile);
     
    			out = new OutputStreamWriter(httpCon.getOutputStream());
    			out.write(new String(bFile));
    			out.flush();
     
    			in = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
    			String sline = null;
    			System.out.println("Reception des donnees retours...");
    			while ((sline = in.readLine()) != null) res.append(sline);
    			System.out.println("[" + res.toString() + "]");
    		} finally {
    			if (fis != null) fis.close();
    			if (out != null) out.close();
    			if (in != null) in.close();
    			if (httpCon != null) httpCon.disconnect();
    		} 
    		return res.toString();
    	}
    Code 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
    System.out.println("com.sellside.web.servlet.ExportListener.processInputStream");
    		File folder = new File(Mem.getProperty("foldercvs") + "/working/mydirectory");
    		if (! folder.exists()) folder.mkdirs();
    		File f_zip = new File(folder, "myZipFile1.zip");
    		PrintWriter pw = null;
    		BufferedInputStream bis = null;
    		int content_length = 0;
    		try {
    			/************HTTP HEADER************/
     
    			Enumeration headerNames = request.getHeaderNames();
    			while(headerNames.hasMoreElements()) {
    				String headerName = (String)headerNames.nextElement();
    				if (headerName.indexOf("content-length") > -1) {
    					content_length = Integer.parseInt(request.getHeader(headerName));
    				}
    				String headerValue = request.getHeader(headerName);
    				System.out.println(headerName + " : " + headerValue);
    			}
     
    			/********************************/
     
    			bis = new BufferedInputStream(request.getInputStream());
    			byte[] contents = new byte[1024];
    			int bytesRead = 0;
    			int sum = 0;
    			StringBuffer sb = new StringBuffer();
    			while( (bytesRead = bis.read(contents)) != -1){
    				sum += bytesRead;
    				System.out.println(sum + " / " + content_length + " ==> " + sum * 100/content_length + "%");
    				sb.append(new String(contents, 0, bytesRead));
    			}
    			pw = new PrintWriter(new FileWriter(f_zip, true));
    			pw.print(sb.toString());
    			pw.flush();
    		} finally {
    			try {
    				if (bis != null) bis.close();
    				if (pw != null) pw.close();
    			} catch(Exception e) {}
    		}
    merci

  2. #2
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    out = new OutputStreamWriter(httpCon.getOutputStream());
    			out.write(new String(bFile));
    			out.flush();
    Le problème vient de là : tu as un tableau de bytes et tu le transformes en String (alors qu'un fichier zip, ça ne se lit pas en tant que chaîne de caractères !)

    Fait ça plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    httpCon.getOutputStream().write(bFile);
    httpCon.flush();
    (en gros, écrite les bytes directement dans le flux)



    Pareil côté serveur : utilises un FileOutputStream plutôt qu'un PrintWriter (qui est utilisé pour les chaînes de caractères, ce qui n'est pas ton cas !)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    			FileoutputStream fos = new FileOutputStream(f_zip);
    			while( (bytesRead = bis.read(contents)) != -1){
    				sum += bytesRead;
    				System.out.println(sum + " / " + content_length + " ==> " + sum * 100/content_length + "%");
    				fos.write(bytesRead);
     
    			}
    			fos.flush();
    			fos.close();
    PS : j'espère que tu enverras jamais de fichier trop gros sinon ça va péter ! (tu charges tout d'un coup là)
    Je ne suis pas mort, j'ai du travail !

  3. #3
    Membre actif
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2013
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 131
    Points : 203
    Points
    203
    Par défaut
    Salut eulbobo,

    J'ai appliqué tes remarques du coté client comme du coté serveur mais cela ne fonctionne toujours pas.
    Avec FileOutputStream coté serveur, le zip ne contient pas l'ensemble des fichiers transférés. j'ai une erreur de la part de winrar des que je double clique sur le ZIP.
    Coté client, j'ai aussi essayé avec un BufferedOutputStream comme tu peux le voir sur le code mais cela ne fonctionne pas non plus.

    Est ce que cela ne pourrait etre du à une histoire d'encoding ?

    Code 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
    private void processInputStream(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		System.out.println("com.sellside.web.servlet.ExportListener.processInputStream");
    		File folder = new File(Mem.getProperty("foldercvs") + "/working/mydirectory");
    		if (! folder.exists()) folder.mkdirs();
    		File f_zip = new File(folder, "myZipFile1.zip");
    		System.out.println(">>>>>>>>>>>>>>>>> " + f_zip.getAbsolutePath());
    		BufferedInputStream bis = null;
    		FileOutputStream fos = null;
    		int content_length = 0;
    		try {
    			/************HTTP HEADER************/
     
    			Enumeration headerNames = request.getHeaderNames();
    			while(headerNames.hasMoreElements()) {
    				String headerName = (String)headerNames.nextElement();
    				if (headerName.indexOf("content-length") > -1) {
    					content_length = Integer.parseInt(request.getHeader(headerName));
    				}
    				String headerValue = request.getHeader(headerName);
    				System.out.println(headerName + " : " + headerValue);
    			}
     
    			/********************************/
     
    			bis = new BufferedInputStream(request.getInputStream());
    			byte[] contents = new byte[1024];
    			int bytesRead = 0;
    			int sum = 0;
    			fos = new FileOutputStream(f_zip, true);
    			while( (bytesRead = bis.read(contents)) != -1){
    				sum += bytesRead;
    				System.out.println(sum + " / " + content_length + " ==> " + sum * 100/content_length + "%");
    				fos.write(contents);
    				fos.flush();
    			}
    		} finally {
    			try {
    				if (bis != null) bis.close();
    				if (fos != null) fos.close();
    			} catch(Exception e) {}
    		}
    }

    Code client :

    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
    static String callHttp(String surl, File f, String login, String pwd) throws Exception {
    		System.out.println("HttpListener.callHttp[" + surl + "//" + login + ":" + pwd + "]: ");
     
    		HttpURLConnection httpCon = null;
    		URL u = null;
    		StringBuffer res = new StringBuffer();
    		FileInputStream fis = null;
    		OutputStream out = null;
    		BufferedReader in = null;
    		BufferedOutputStream bos = null;
    		try {
    			u = new URL(surl);
    			httpCon = (HttpURLConnection) u.openConnection();
    			System.out.println("filesizeeeeeeeeee = " + f.length());
    			httpCon.setDoOutput(true);
    			httpCon.setDoInput(true);
    			httpCon.setRequestProperty("Content-Type", "application/zip");
     
    			byte[] bFile = new byte[(int) f.length()];
    			fis = new FileInputStream(f);
    			fis.read(bFile);
    			out = httpCon.getOutputStream();
    			out.write(bFile);
    			out.flush();
    			/*bos = new BufferedOutputStream(httpCon.getOutputStream());
    			bos.write(bFile);
    			bos.flush();*/
     
    			System.out.println("REQUETE ENVOYEEEEEEEEEEEEEEEEEEEEEEEEE");
    			in = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
    			String sline = null;
    			System.out.println("Reception des donnees retours...");
    			while ((sline = in.readLine()) != null) res.append(sline);
    			System.out.println("[" + res.toString() + "]");
    		} finally {
    			if (fis != null) fis.close();
    			if (out != null) out.close();
    			if (in != null) in.close();
    			if (httpCon != null) httpCon.disconnect();
    		} 
    		return res.toString();
    	}

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Bon, déjà c'est mieux parce qu'on n'utilise pas les reader / writer.

    Maintenant ton code démontre une méconnaissance du protocol http et possède encode quelques erreurs:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    			byte[] bFile = new byte[(int) f.length()];
    			fis = new FileInputStream(f);
    			fis.read(bFile);
    			out = httpCon.getOutputStream();
    			out.write(bFile);
    Tu suppose que read va remplir ton tableau de byte, ce n'est pas nécessairement vrai. read lit au plus la taille de ton tableau mais peu lire moins. Il lit uniquement ce qui est disponible comme données à l'instant T. Comme tu peux le voir dans cette FAQ, il y a un peu plus de travail pour transférer l'intégralité d'un inputstream dans un outputstream.
    http://java.developpez.com/faq/java/...FICHIER_copier

    Alternativement, pour pas te casser la nenette tu peux utiliser en ne ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Files.copy(Paths.get(filename),out);

    Tu fais une erreur similaire dans ton serveur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    			while( (bytesRead = bis.read(contents)) != -1){
    				sum += bytesRead;
    				System.out.println(sum + " / " + content_length + " ==> " + sum * 100/content_length + "%");
    				fos.write(contents);
    				fos.flush();
    			}
    byteRead te dit combien de byte on été lus, mais tu transfère l'intégralité du tableau, y compris le caca à la fin qui ne viens pas de la lecture, dans le fichier. Tu as reçu byteRead comme information, utilise là. Sinon, si inputstream lit 100 bytes, tu écrit dans le fichier ces 100 bytes plus 924 bytes qui n'ont rien à voir, pour ensuite passer au reste du fichier. Forcément à l'arrivée le fichier ne ressemble plus à rien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    			while( (bytesRead = bis.read(contents)) != -1){
    				sum += bytesRead;
    				System.out.println(sum + " / " + content_length + " ==> " + sum * 100/content_length + "%");
    				fos.write(contents,0,bytesRead);
    				fos.flush();
    			}
    Encore une fois, ce code peux être simplifié:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Files.copy(bis,f_zip.toPath());
    Enfin, je ne sais pas sur quoi est branché ton processInputStream, mais je te recommanderait de faire un HTTP PUT plutot que le HTTP POST que tu fais actuellement. Je ne suis pas sur à 100% que cela changera grand chose au process, mais au moins la méthode HTTP utilisée sera cohérente avec le travail que fait le serveur. POST est plutot destiné à des formulaire soumis et le serveur peut être tenté de décoder le contenu du inputstream lui même.

  5. #5
    Membre actif
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2013
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 131
    Points : 203
    Points
    203
    Par défaut
    Super cela fonctionne, merci à vous deux pour votre aide.

    derniere question :

    Est ce que le MIME dans le header à vraiment son importance ?

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

Discussions similaires

  1. Envoi fichier vers un serveur en https
    Par new70 dans le forum Unix
    Réponses: 2
    Dernier message: 16/01/2015, 13h21
  2. [Débuter] Envoi de données par POST en HTTP
    Par Heroiik dans le forum Réseau
    Réponses: 5
    Dernier message: 31/07/2013, 18h34
  3. [Batch] Supprimer de fichier .pdf dans un dossier zippé à partir d'une liste
    Par Gardel dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 09/11/2010, 12h35
  4. Taille d'un dossier (zippé et non zippé)
    Par womannosky dans le forum Collection et Stream
    Réponses: 9
    Dernier message: 21/06/2009, 17h58
  5. [HTTP] Envoi de fichiers par http
    Par Delendial dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 03/09/2004, 09h37

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