2010-02-17 5 views
8

[Java 1.5; Eclipse Galileo]HttpsURLConnection se bloque lorsque getInputStream() est appelé

HttpsURLConnection semble se bloquer lorsque la méthode getInputStream() est appelée. J'ai essayé d'utiliser différents sites Web en vain (actuellement https://www.google.com). Je dois souligner que j'utilise http S.

Le code ci-dessous a été modifié en fonction de ce que j'ai appris des autres réponses de StackOverflow. Cependant, aucune des solutions que j'ai essayées jusqu'ici n'a fonctionné.

Je serais très reconnaissant pour un coup de coude dans la bonne direction :)

public static void request(URL url, String query) 
{ 
try{ 

    HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 

    //connection.setReadTimeout(5000); //<-- uncommenting this line at least allows a timeout error to be thrown 

    connection.setDoInput(true); 
    connection.setDoOutput(true); 
    connection.setUseCaches(false); 
    System.setProperty("http.keepAlive", "false"); 


    connection.setRequestMethod("POST"); 


    // setting headers 
    connection.setRequestProperty("Content-length",String.valueOf (query.length())); 
    connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); //WAS application/x-www- form-urlencoded 
    connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)"); 

    //////////////////////////////////////////////////////////////////////////////////// 
    //////////////////////////////////////////////////////////////////////////////////// 
    System.out.println("THIS line stalls" + connection.getInputStream()); 
    //////////////////////////////////////////////////////////////////////////////////// 

}catch(Exception e) { 
    System.out.println(e); 
    e.printStackTrace(); 
} 

erreurs typiques ressemblent:

java.net.SocketTimeoutException: Read timed out 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:129) 
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293) 
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:782) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:739) 
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75) 
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) 
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256) 
at java.io.BufferedInputStream.read(BufferedInputStream.java:313) 
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:681) 
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:626) 
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:983) 
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234) 
at https_understanding.HTTPSRequest.request(HTTPSRequest.java:60) 
at https_understanding.Main.main(Main.java:17) 
+0

Juste un coup de poignard dans le noir, vous envoyez une requête POST, donc je suppose que l'autre extrémité (Google) vous attend d'envoyer certains paramètres. Tout ce que vous envoyez est des en-têtes HTTP. Que se passe-t-il lorsque vous modifiez POST à ​​un GET? – beny23

+0

Que faites-vous/vraiment/que vous essayez de faire? Votre balise gmail me porte à soupçonner que vous pourriez être mieux avec POP, IMAP, ou SMTP (ou l'une des API personnalisées de Google) –

Répondre

5
connection.setDoOutput(true); 

Cela signifie que vous devez ouvrir, écrire à et fermez le flux de sortie de la connexion avant d'essayer de lire à partir de son flux d'entrée. Voir the docs.

+0

Cela définit implicitement la méthode de demande à 'POST' lorsque le protocole HTTP est utilisé dans l'URL, en d'autres termes , le 'connection.setRequestMethod (" POST ");' est entièrement superflus (comme le downcast à 'HttpUrlConnection'). Faites un 'connection.getOutputStream(). Close()' si vous avez l'intention de lancer un POST sans aucun paramètre de requête (ce qui n'a aucun sens, mais OK;)). – BalusC

+3

cela n'a rien fait pour résoudre le problème –

2

De même, ne définissez pas l'en-tête de longueur de contenu. Java le fera pour vous.

+0

Merci pour le conseil :) – geraldalewis

3

Je reproduit le problème dans Android 2.2: lors du téléchargement à partir d'un serveur Web sur sans fil et une URL HTTPS, l'erreur est une prise « lecture temps » à URLConnection.getInputStream()

Pour fixer, utilisez url.openStream() pour le InputStream au lieu de connection.getInputStream()

Bonus: vous pouvez obtenir la longueur du fichier que vous téléchargez, vous pouvez alors afficher un indicateur complet%

exemple de code:

private final int TIMEOUT_CONNECTION = 5000;//5sec 
private final int TIMEOUT_SOCKET = 30000;//30sec 

file = new File(strFullPath); 
URL url = new URL(strURL); 
URLConnection ucon = url.openConnection(); 

//this timeout affects how long it takes for the app to realize there's a connection problem 
ucon.setReadTimeout(TIMEOUT_CONNECTION); 
ucon.setConnectTimeout(TIMEOUT_SOCKET); 


//IMPORTANT UPDATE: 
// ucon.getInputStream() often times-out over wireless 
// so, replace it with ucon.connect() and url.openStream() 
ucon.connect(); 
iFileLength = ucon.getContentLength();//returns -1 if not set in response header 

if (iFileLength != -1) 
{ 
    Log.i(TAG, "Expected Filelength = "+String.valueOf(iFileLength)+" bytes"); 
} 

//Define InputStreams to read from the URLConnection. 
// uses 5KB download buffer 
InputStream is = url.openStream();//ucon.getInputStream(); 
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5); 
outStream = new FileOutputStream(file); 
bFileOpen = true; 
byte[] buff = new byte[5 * 1024]; 

//Read bytes (and store them) until there is nothing more to read(-1) 
int total=0; 
int len; 
int percentdone; 
int percentdonelast=0; 
while ((len = inStream.read(buff)) != -1) 
{ 
    //write to file 
    outStream.write(buff,0,len); 

    //calculate percent done 
    if (iFileLength != -1) 
    { 
     total+=len; 
     percentdone=(int)(total*100/iFileLength); 

     //limit the number of messages to no more than one message every 10% 
     if ((percentdone - percentdonelast) > 10) 
     { 
      percentdonelast = percentdone; 
      Log.i(TAG,String.valueOf(percentdone)+"%"); 
     } 
    } 
} 

//clean up 
outStream.flush();//THIS IS VERY IMPORTANT ! 
outStream.close(); 
bFileOpen = false; 
inStream.close(); 
Questions connexes