2010-02-17 4 views
8

[Java 1.5; Eclipse Galileo]HttpsURLConnection stallo quando getInputStream() è chiamato

HttpsURLConnection sembra arrestarsi quando viene chiamato il metodo getInputStream(). Ho provato a utilizzare diversi siti web senza alcun risultato (attualmente https://www.google.com). Devo sottolineare che sto usando http S.

Il codice seguente è stato modificato in base a ciò che ho appreso da altre risposte StackOverflow. Tuttavia, nessuna soluzione che ho provato finora ha funzionato.

Sarei molto grato per una gomitata nella giusta direzione :)

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(); 
} 

errori tipici assomigliano:

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

Solo un salto nel buio, si invia una richiesta POST, quindi presumo che l'altra estremità (google) è in attesa per l'invio di alcuni parametri. Tutto quello che stai inviando sono alcune intestazioni HTTP. Cosa succede quando cambi POST in GET? – beny23

+0

Cosa stai/davvero/cercando di fare? Il tuo tag Gmail mi porta a sospettare che potresti stare meglio con POP, IMAP o SMTP (o con una delle API personalizzate di Google) –

risposta

5
connection.setDoOutput(true); 

Questo significa che si deve aprire, scrivere a, e chiudere il flusso di output della connessione prima di tentare di leggere dal suo flusso di input. Vedi the docs.

+0

Questo imposta anche implicitamente il metodo di richiesta a 'POST' quando il protocollo HTTP viene utilizzato nell'URL, in altre parole , 'connection.setRequestMethod (" POST ");' è interamente superfluo (come il downcast di 'HttpUrlConnection'). Effettuate un 'connection.getOutputStream(). Close()' se intendete attivare un POST senza parametri di richiesta (che non ha senso, ma OK;)). – BalusC

+3

questo non ha fatto nulla per risolvere il problema –

2

Inoltre, non impostare l'intestazione della lunghezza del contenuto. Java lo farà per te.

+0

Grazie per il suggerimento :) – geraldalewis

3

ho riprodotto il problema in Android 2.2: durante il download da un server web su reti wireless e un URL HTTPS, l'errore è una presa di "lettura time out" a URLConnection.getInputStream()

Per risolvere il problema, utilizzare url.openStream() per l'InputStream invece di connection.getInputStream()

Bonus: è possibile ottenere la lunghezza del file che si sta scaricando in modo da poter mostrare un indicatore completo%

codice di esempio:

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();