Servlet: la réponse.setContentLength() ralentit le téléchargement en bas
private void downloadAllRelease(HttpServletRequest request,
HttpServletResponse response) {
LoginToken tok=getToken(request, response);
int size = 0;
try {
ArrayList<Release> releases = manager.getReleases(tok.getUsername);
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
for (int i=0; i<releases.size(); i++) {
size += releases.get(i).getFile().length;
out.putNextEntry(new ZipEntry(releases.get(i).getFilename()));
out.write(releases.get(i).getFile());
out.closeEntry();
}
response.setContentLength(size);
response.setContentType("application/force-download");
response.setHeader("Content-Disposition","attachment;filename=release.zip");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
response.setContentLength()
reeeeally ralentit les téléchargements vers le bas.
Si je ne l'utilise pas ou le mettre après out.close()
tout fonctionne toujours bien, mais les téléchargements sont muuuuch plus rapide.
Quelqu'un peut-il m'expliquer pourquoi et si il est nécessaire d'utiliser response.setContentLength()
?
Votre question résolu un problème que j'ai avec servlet-api-3.1 dans la Jetée 9. J'ai enlevé la réponse.setContetLength() dans ma servlet; le temps de réponse correspond maintenant à ce que j'obtenais avec les précédents Jetée versions.
Heureux d'avoir eu de l'aide.
Heureux d'avoir eu de l'aide.
OriginalL'auteur Simon | 2012-01-10
Vous devez vous connecter pour publier un commentaire.
Peut-être parce que vous êtes en spécifiant une taille de plus que ce qui est réellement été envoyé à la réponse et le contrôle webbrowser, fondamentalement, de la confusion et est en attente pour plus de données? Vous savez, ZIP compresse les fichiers et réduit la taille finale.
Il suffit de ne pas préciser la réponse de la longueur du contenu si vous ne pouvez pas efficacement le calculer à l'avance. Le conteneur de servlet va automatiquement l'envoyer avec fragments de codage de toute façon. Vrai, il a un peu plus de frais généraux et quitte le webbrowser avec un inconnu de la progression du téléchargement, mais cela ne vous demandera pas de tampon de la totalité de la réponse dans la mémoire du serveur en premier, de sorte que vous pouvez obtenir la bonne réponse finale de longueur de contenu.
Si vous vraiment voulez calculer le contenu de la réponse de longueur, vous aurez besoin d'écrire tout cela à un
ByteArrayOutputStream
au lieu de cela, puis obtenir lebyte[]
par sontoByteArray()
méthode. Le véritable contenu de la réponse de la longueur est la longueur de labyte[]
.Ce n'est plus de la mémoire monopolisant parce que tout sera stocké dans la mémoire du serveur en premier. Si plusieurs utilisateurs à faire simultanément, et le zip de sortie est relativement grande, alors le serveur a peut-risque de manquer de mémoire, tôt ou tard. Comme autre alternative, vous pouvez écrire à l'aide de
FileOutputStream
à un fichier temporaire créé parFile#createTempFile()
, de sorte que vous pouvez obtenir la taille enFile#length()
et l'utilisationFileInputStream
le lire directement dans leOutputStream
de la réponse de la manière habituelle. C'est plus lent que vous êtes essentiellement en transférant les octets près de deux fois.Appuyez simplement sur "Poser une Question" bouton en haut à droite pour obtenir une réponse.
OriginalL'auteur BalusC