2009-07-31 10 views
3

Je suis perplexe à ce sujet, alors j'ai pensé que je demanderais au cas où vous l'auriez rencontré, puisque le développement HttpClient est un peu un art. Le problème auquel je suis confronté est le suivant: Une application utilise la bibliothèque Apache HttpClient Java pour communiquer avec un serveur dans le même réseau d'entreprise. La plupart du temps, cela fonctionne sans problème, mais à l'occasion nous verrons un barrage d'exceptions causé par des réponses incomplètes: les trois derniers caractères de la balise fermante leur manquent, de sorte que l'analyseur du client se plaint. Cela dure peut-être 5 à 10 minutes, puis s'en va.Réponse intermittente incomplète à l'aide d'Apache HttpClient 3.0.1

Je n'ai pas été en mesure de répliquer ce problème localement, et j'ai vérifié que la réponse est écrite complètement par le serveur. Le client obtient le contenu de la réponse avec la méthode getResponseBodyAsStream() de PostMethod, mais il n'est appelé qu'une seule fois. Peut-être qu'il a besoin de boucler l'appel de cette méthode jusqu'à ce qu'il obtienne null pour l'occasion rare où la réponse est mise en mémoire tampon?

J'apprécierai n'importe quelle entrée.

Edit: Le serveur est en train d'écrire l'en-tête de longueur du contenu et de rinçage correctement, et au niveau du client, les données sont lues dans une chaîne avec:

//method is a PostMethod, client is a HttpClient 
client.executeMethod(hostconfig, method); 

InputStream is = method.getResponseBodyAsStream(); 
String response = null; 

try { 
    ByteArrayOutputStream bos = new ByteArrayOutputStream();  
    byte[] buf = new byte[1024]; 
    int len; 

    while ((len = is.read(buf)) > 0) { 
     bos.write(buf, 0, len); 
    } 

    response = new String(bos.toByteArray(), "UTF-8"); 

} ... // closing try block 
+0

Edit: Comme avec de nombreux bugs difficiles à trouver, le problème semble être lié à des caractères spéciaux (caractères accentués européens, long-s allemand et ainsi de suite). Une fois les messages normalisés pour supprimer ces caractères, les erreurs se sont arrêtées. – Munir

+0

Avoir un problème similaire. Exact même URL. En utilisant le navigateur/Curl donnez-moi les données complètes. Mais, Httpclient obtient une sortie incomplète ...! – thinkanotherone

Répondre

1

sont-les en-têtes de longueur du contenu de la sever étant fixés correctement? Je ne suis pas sûr à 100% si le Commons-HttpClient les respecte ou pas, mais il pourrait facilement le faire. Je ne vois aucune raison pour laquelle vous auriez besoin d'appeler à plusieurs reprises getResponseBodyAsStream.

Il est également concevable que votre code pour lire le flux fasse de fausses suppositions. Peut-être que nous pourrions voir un extrait de la façon dont vous lisez les données pour vous assurer que vous lisez réellement le flux entier correctement? Certaines erreurs de codage courantes peuvent conduire à une lecture jusqu'à une valeur tampon (ce qui entraînera des échecs apparemment aléatoires). En dehors de cela, c'est difficile à dire ... nous utilisons régulièrement HttpClient Commons sans symptômes similaires.

+0

Hey jsight, merci d'avoir répondu. J'ai édité la question pour clarifier.Le serveur écrit les en-têtes correctement et chasse, et j'ai ajouté le code qui lit du Stream. J'ai également regardé dans la configuration HttpClient qui est utilisée par le client et la seule chose qui m'a sauté était le paramètre explicite du paramètre Linger-on-timeout à 0 (désactivé). – Munir

1

J'ai également été confronté à ce problème. Ce problème est apparu seulement après avoir changé l'URL de localhost en un public.

J'ai trouvé quelques solutions ...

La première « solution » j'ai trouvé était d'exécuter un Thread.sleep (1000) avant de lancer le processus de lecture. Je pense que cela provoque le remplissage du tampon avant d'essayer de lire. (Je sais que cela n'a pas de sens puisque read() indique qu'il bloque jusqu'à ce que les données soient disponibles, mais malheureusement la méthode de lecture pense parfois qu'elle a atteint la fin plus tôt que prévu). Cela ressemble plus à un patch moche, donc je continue à chercher ...

La deuxième option et la meilleure est d'utiliser la méthode readLine() de BufferedReader. Cette méthode implémente correctement le processus de lecture. Je n'ai pas lu le code source de readLine mais je pense que nous pourrions trouver la solution à notre problème.

Salutations.