8

[Java 1.5; エクリプス・ガリレオ】

getInputStream() メソッドが呼び出されると、HttpsURLConnection が停止するようです。別の Web サイトを使用してみましたが、役に立ちませんでした (現在はhttps://www.google.com )。私は http Sを使用していることを指摘しておく必要があります。

以下のコードは、他の StackOverflow の回答から学んだことに基づいて変更されています。ただし、これまで試した解決策は機能しませんでした。

私は正しい方向への微調整に非常に感謝しています:)

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

典型的なエラーは次のようになります。

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)
4

3 に答える 3

5
connection.setDoOutput(true);

これは、入力ストリームから読み取る前に、接続の出力ストリームを開き、書き込み、閉じる必要があることを意味します。ドキュメントを参照してください。

于 2010-02-17T03:37:03.607 に答える
3

Android 2.2 で問題を再現しました。ワイヤレスおよび HTTPS URL を介して Web サーバーからダウンロードすると、エラーは URLConnection.getInputStream() でのソケットの「読み取りタイムアウト」です。

これを修正するには、inputStream に connection.getInputStream() の代わりに url.openStream() を使用します。

ボーナス:ダウンロードしているファイルの長さを取得できるので、完了率のインジケーターを表示できます

コードサンプル:

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();
于 2011-12-16T00:26:50.033 に答える
2

また、content-lengthヘッダーを設定しないでください。Javaがあなたに代わってそれを行います。

于 2010-02-17T23:17:29.237 に答える