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

Servlets/JSP Java Discussion :

Servlet de téléchargement (Resin)


Sujet :

Servlets/JSP Java

  1. #1
    Futur Membre du Club
    Profil pro
    Développeur Java
    Inscrit en
    Juillet 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2009
    Messages : 4
    Par défaut Servlet de téléchargement (Resin)
    Bonjour,

    J'essaye depuis plusieurs jours de réaliser une servlet de téléchargement de fichier depuis un navigateur(Serveur Caucho Resin 3.1.6).
    L'utilisateur sélectionne le fichier par le biais d'un moteur de recherche etc...
    J'ai deja fait ce genre de servlet plusieurs fois mais je rencontre quelques problèmes de cahier des charges avec ce projet:

    - Lorsque l'utilisateur annule le téléchargement (a l'invite de sauvegarde, ou pendant le téléchargement), la boucle d'envoi de ma servlet continue sans fin , pas d'exception(comme je l'aurai espérer), pas de fermeture du flux, rien.

    Pas de souci a priori, sauf quand les fichiers a envoyé par le serveur peuvent faire plusieurs centaines de Mo et que plusieurs utilisateurs peuvent télécharger en même temps. Donc l'utilisateur clique sur télécharger, annule , et ma servlet mouline jusqu'à ce qu'elle est transférer tout le contenu du flux du fichier vers le flux (fantôme) de la réponse (sic ). D'un point de vue optimisation des ressource c'est une catastrophe.

    J'ai sniffer le réseaux avec wireshark , quand l'utilisateur annule, le flux http s'arrête, et le client envoi au serveur un RST ACK (royalement ignoré)

    J'ai fait part de ce comportement étrange a mes collègues et ils n'avait jamais réalisé l'existence de ce problème, de même après avoir cherché longuement sur internet j'ai l'impression que personne n'a jamais remarqué cela, ou personne n'a ce problème, ou alors personne ne s'en préoccupe.

    Voici le code de ma servlet (sans les traces)
    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
     
    	File f;
    	UserFile uf;
    	BinaryFile bf;
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    	throws ServletException, IOException {
    		super.doGet(req, resp);
    		if(getSessionAccess()==null){
    			resp.sendRedirect("Login");
    			return;
    		}
     
    		//TODO logs Download on UserFile, BinaryFile and DownloadLog 
    		getFile(req.getParameter("file"));
     
    		f = new File(bf.getAbsolutePath());
    		if(!f.exists()){
    			throw new FileNotFoundException("File not found: "+bf.getId());
    		}
     
    		int                 length   = 0;
    		ServletOutputStream sout       = resp.getOutputStream();
    		ServletContext      context  = getServletConfig().getServletContext();
    		String              mimetype = context.getMimeType( f.getAbsolutePath() );
     
    		//  Setup the httpResponse
     
    		resp.reset();
    		resp.setContentType( (mimetype != null) ? mimetype : "application/octet-stream" );
    		resp.setBufferSize(10240);
    		resp.setHeader( "Content-Disposition", "attachment; filename=\"" + uf.getUfName() + "\"" );
    		resp.setContentLength((int)f.length());
     
    		//  Stream to the requester.
    		byte[] bbuf = new byte[10240];
    		DataInputStream in = new DataInputStream(new FileInputStream(f));
     
    		while ((in != null) && ((length = in.read(bbuf)) != -1))
    		{
    			try {
    				//Used to slow down file upload , otherwise localhost testing require superhuman speed
    				Thread.sleep(1);
    			} catch (InterruptedException e) {
    				System.err.println("Download interrupted");
    			}
    			try{
    				sout.write(bbuf,0,length);
    				sout.flush();
    			}catch(IOException ioe){
    				ioe.printStackTrace();
    			}
     
    		}
    		in.close();
    		sout.flush();
    		sout.close();
    		//TODO update Downloaded logs
     
    	}
    J'ai essayer avec plusieurs type de flux : Buffered, Channel ...

    En désespoir de cause je soupçonne le conteneur d'être responsable de cela, j'ai du mal a admettre que ce soit logique de la part des concepteur qu'une servlet puisse faire un traitement long de ce type pour faire plaisir a un navigateur éteint .

    Si vous avez une idée ou un indice qui pourrais m'aidez a avancer je vous en serais très reconnaissant.

  2. #2
    Futur Membre du Club
    Profil pro
    Développeur Java
    Inscrit en
    Juillet 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2009
    Messages : 4
    Par défaut
    J'ai tester sous GlassFish , même constat.

    C'est logique que le serveur ne soit pas en mesure de récupérer directement les informations du client (étant donnée le que protocole http est purement du type requete->réponse).

    Mais j'ai du mal a imaginer qu'il n'y ai aucun moyen de contrôler la continuité du flux dans le cas de gros fichier, cela voudrait dire que les sites qui proposent de gros fichiers en téléchargement ne sont pas non plus capable d'arrêter l'envoi même si la connexion est interrompu. (Cela expliquerai en revanche les timers important entre deux téléchargements successif sur les sites dont je parle, sinon il serait trop facile de les surcharger).

    D'un autre coté ces sites sont capables de tenir compte d'une annulation a l'invite d'enregistrement (dans ce cas il est possible de reprendre un autre téléchargement sans devoir attendre).

    J'ai également tester l'activité de la session utilisateur pendant l'envoi du fichier, celle ci ne se met pas a jour , impossible donc de mettre un timeout pour la session au risque que les téléchargements prenant plus de temps que ce timeout n'aboutissent jamais.

    Personne n'a jamais été confronté à cela ?
    C'est un faux problème (peut importe que le serveur continue de lire les 500Mo restant du fichier demandé après annulation) ?

    Dans le pire des cas je ferais des tentative pour coder l'envoi directement en socket mais j'aimerai éviter d'en arriver là.

Discussions similaires

  1. Téléchargement de gros fichiers depuis un Servlet
    Par Simvetanylen dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 08/06/2011, 15h24
  2. Réponses: 3
    Dernier message: 15/04/2009, 17h03
  3. Proposer un téléchargement
    Par chunly dans le forum Flash
    Réponses: 4
    Dernier message: 03/05/2006, 09h43
  4. Bloquer le téléchargement de certains types de fichiers
    Par Nikos dans le forum Développement
    Réponses: 4
    Dernier message: 23/12/2002, 20h54

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