2017-01-03 2 views
1

J'ai un gestionnaire dans un déploiement de serveur jetée, qui fait référence à l'objet HttpServletResponse.Définition de la longueur du contenu dans l'objet de réponse http après l'écriture dans OutputStream

Je vous écris contenu des octets à la Response.getOutputStream() comme ci-dessous:

ServletOutputStream serlvetOutputStream = handlerContext.getResponse().getOutputStream(); 
... 
while(condition) { 
//read chunk from some source into byteBuffer 
servletOutputStream.write(byteBuffer, 0, lengthRead); 
} 

Mais avant Je peux écrire écrire(), je dois régler la longueur du contenu du client http attend dans le réponse:

handlerContext.getResponse().setContentLength((int) length); //or as below 
handlerContext.getResponse().addHeader("Content-Length", String.valueOf(length)); 

défaut de régler la longueur avant d'écrire à la outputstream, se traduit par une fenêtre pop-up « erreur taille du fichier inconnu » sur l'application client Windows. Mais dans certains cas, je ne saurais pas quelle serait la longueur à écrire avant. Je ne peux pas accumuler la totalité des données à lire à l'avance (car il peut temporiser le client pour des données plus volumineuses) donc il doit être «tronqué» en lisant x kilo-octets puis écrire x kilooctets, jusqu'à ce que la condition soit fausse.

Ma question est - est-il possible de mettre à jour dynamiquement la longueur du contenu juste avant d'écrire? Dans la boucle ci-dessus, je veux définir la longueur du contenu comme si de nombreux octets étaient disponibles pour écrire, écrire() ceux-ci, puis le mettre à jour quand il boucle.

Si je mets à jour la longueur de contenu dans la boucle, j'obtiens jetty.server.EoFexception.

+1

Si vous lisez les données fragmentées et que vous ne pouvez pas mettre en mémoire tampon l'ensemble des données en Java, vous ne pouvez pas connaître la quantité réelle lue. Y a-t-il une chance que vous puissiez estimer la longueur du contenu ou est-ce que l'API à partir de laquelle vous lisez pourrait fournir une estimation? –

+1

Comme son nom l'indique, Content-Length est un en-tête qui peut être défini une seule fois au début de votre réponse. En fonction de l'origine de vos données (fichier, blob, etc.), vérifiez s'il existe des métadonnées à partir desquelles vous pouvez interroger la longueur attendue avant de diffuser le contenu. Sinon, vous devrez peut-être mettre en mémoire tampon le flux entier (en mémoire ou sur disque), déterminer sa longueur, puis définir l'en-tête et démarrer la réponse. Enfin, si la longueur du contenu est vraiment impossible à déterminer d'emblée, regardez dans la mise à jour du client et regardez dans les protocoles HTTP ou de streaming. –

+1

Les en-têtes peuvent uniquement être envoyés avant le contenu réel, c'est comme cela que fonctionne HTTP. –

Répondre

2

Vous n'avez pas besoin de définir la longueur du contenu. Cela va arriver automatiquement. Ce que vous avez ici est un problème XY. Vous avez une exception non divulguée et vous pensez que la définition de la longueur du contenu le résoudra. Cependant, comme vous ne pouvez pas non plus définir la longueur du contenu, vous n'avez aucune preuve réelle de votre croyance.

+0

Le client est une application Windows et renvoie une erreur si la longueur du contenu est manquante. – PKM

+0

Il jette * quelle * exception? Et où est votre preuve que la fourniture d'une longueur de contenu va le réparer? – EJP

+0

Si je définis manuellement la longueur du contenu pour une taille de contenu connue, il ne se plaint pas. J'ai vu (en utilisant Wireshark) que le client avait un paquet avec une longueur de contenu. Modifierait "Exception" sur le client avec une "erreur" - une boîte pop-up indiquant "Erreur taille inconnue". – PKM