HttpURLConnection Post: flux de Sortie n'a pas d'effet?
Je développe une application Android et ont déjà constaté que les différentes versions d'Android ont différentes manières sur la façon dont ils gèrent Http(s)URLConnections (http://stackoverflow.com/q/9556316/151682).
J'ai couru dans la question que Android 4 effectue une requête POST sur HTTPS joliment, ajouter des en-têtes comme Type de Contenu automatiquement lors de l'exécution du code ci-dessous.
Cependant, sur Android 2.3.5 (périphérique & émulateur), une écriture sur le flux de sortie semble être ignoré - je débogué avec le proxy web Charles et alors que tous les en-têtes sont envoyées, les données écrites sur le flux de sortie n'est pas envoyé...
Quelqu'un sait comment résoudre ce problème?
Remarque: Comme les API je suis en développement, contre seulement un certificat auto-signé, j'ai besoin de désactiver la validation de certification en ce moment.
TIA, Patrick
Mise à jour
En attendant, j'ai aussi essayé de suite, en vain:
- Appel
close()
après laflush()
appel sur le BufferedOutputStream - Appel
close()
sur le OutputStream et la BufferedOutputStream - À l'aide d'un OutputStreamWriter au lieu
-
Ne pas appeler
close()
avant d'appelergetInputStream()
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(CONNECT_TIMEOUT); connection.setDoOutput(true); //Triggers POST. connection.setRequestMethod("POST"); int contentLength = 0; if(body != null) { contentLength = body.getBytes().length; } //Workarounds for older Android versions who do not do that automatically (2.3.5 for example) connection.setRequestProperty(HTTP.TARGET_HOST, url.getHost()); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //Set SSL Context -- Development only if(context != null && connection instanceof HttpsURLConnection){ HttpsURLConnection conn = (HttpsURLConnection)connection; conn.setSSLSocketFactory(context.getSocketFactory()); conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); } try{ //Add headers if(headers != null){ for (NameValuePair nvp : headers) { if(nvp != null){ connection.setRequestProperty(nvp.getName(), nvp.getValue()); } } } connection.setFixedLengthStreamingMode(contentLength); OutputStream outputStream = null; try { if(body != null){ outputStream = connection.getOutputStream(); BufferedOutputStream stream = new BufferedOutputStream(outputStream); stream.write(body.getBytes()); //<<<< No effect ?! stream.flush(); } } finally { if (outputStream != null) try { outputStream.close(); } catch (IOException logOrIgnore) { //... } } InputStream inputStream = connection.getInputStream(); //.... Normal case .... } catch(IOException e){ //... Exception! Check Error stream and the response code ... } finally{ connection.disconnect(); }
}
body != null
et contentLength > 0
? Avez-vous fait une session ou de vérifier toutes les exceptions qui peuvent se produire dans le bloc try? Qu'est-ce que le code de réponse du serveur?code de réponse du serveur est de 400 bad request, je ne les enregistre, mais par souci de concision omis ici... Il ne parvient pas à "getInputStream". le corps est vérifié pour les nuls-ness avant d'écrire dans le flux. ContentLength n'est pas explicitement vérifiées ici (merci pour la suggestion), mais il est conforme avec le corps passé, chaque fois que je le vérifie.
OriginalL'auteur Patrick | 2012-04-07
Vous devez vous connecter pour publier un commentaire.
Il me semble que l'ordre dans lequel vous appelez
DoSetOutput
etc. c'est la raison pour le comportement étrange...Quelques liens/source code du travail pour HTTP POST sur Android:
^^ Commentaire mis à jour, j'ai toujours la touche Entrée pour début
vous êtes les bienvenus 🙂 je ne suis pas vraiment sûr... mais je vous recommande d'essayer le
DefaultHttpClient
sur des échantillons...En fait je voulais vraiment utiliser HttpURLConnection puisque leur utilisation est particulièrement recommandée pour les nouvelles Applications de l'Android de l'équipe... (android-developers.blogspot.com/2011/09/...) Mais j'aurais du économiser beaucoup de tracas avec DefaultHttpClient, c'est vrai 😉
la plupart des exemples ci-dessus utilisent
HttpURLConnection
et certains peuvent même être utilisé comme une copie&pâte de remplacement pour votre code...OriginalL'auteur Yahia
Ah, je l'ai finalement trouvé. La recherche dans le mauvais endroit... Le problème était les en-têtes:
Mon code ci-dessus fonctionne réellement amende - la cause est que j'ai inclus un en-tête qui est encodé en Base64. Sur mon Android 2.3.5 l'option spécifiée (
Base64.DEFAULT
) semble pour insérer un saut de ligne supplémentaire à la fin qui se termine à la demande prématurément, ce qui me donne pas le temps d'envoyer le corps réel.Sur Android 4, la valeur par Défaut semble être changé pour quelque chose comme BASE64.NO_WRAP comme expliqué dans le post en lien ci-dessous...
Ce n'était en fait déjà répondu ici.
Merci pour vos efforts.
OriginalL'auteur Patrick