4

java.net.HttpURLConnection単純なHTTPGET呼び出しを行うために使用しようとしていますが、説明できない問題が発生しています。

public String makeGETCall(HttpURLConnection con) {
    try {
        System.out.println("About to make the request...");

        if(con == null)
            System.out.println("con is NULL");
        else {
            System.out.println("con is NOT null");

            if(con.getInputStream() == null)
                System.out.println("con's input stream is NULL");
            else
                System.out.println("con's input stream is NOT null");
        }
    } catch(Throwable t) {
        System.out.println("Error: " + t.getMessage());
    }

    System.out.println("Returning...")
    return "DUMMY DATA";
}

これを実行すると、次のコンソール出力が得られます。

About to make the request...
con is NOT null

そして、プログラムはエラーなしで終了します。例外がスローされることはなく、予期せず終了することも、ハングしたりタイムアウトしたりすることもありません...ただ死ぬだけです。

con.getInputStream()あるかどうかを確認すると死にかけているようnullです。しかし、それでも、エラーの兆候がなく、静かに死ぬ理由は説明されていません。何か案は?私は間違って作成した可能性があることを認めたいと思いますがHttpURLConnection、それでも、私のプログラムを殺しているもののより多くの兆候があるはずです...事前に感謝します!

4

4 に答える 4

1

この行以降、コードはコンパイルされていないはずです。

 System.out.println("Returning...")

セミコロンがありません。そうは言っても、使用しているアプリケーションの実行は古い実行を使用しており、おそらく作成した新しいコードがないことを想像します。

そうでない場合は、コードを誤って(どういうわけか)貼り付けており、私たちが確認する必要のある他の側面を見逃していると思いますか?StackOverflowのコードを何らかの方法で編集した場合は、元のコードを共有していただけませんか?

Throwableまた、正当な理由がない限り、捕まえないことをお勧めします。アプリケーションエラーをそのようにマスクすることは、通常、悪い習慣です。

于 2013-03-01T14:54:06.507 に答える
0

con.getInputStream()nullかどうかをチェックすると死にかけているようです。

まあ、それは信じがたいことだと思います。

それに直面して:

  • 参照をテストしてnull、プログラムを終了できないかどうかを確認します

  • con.getInputStream()例外をスローするか、返すことができます

  • 返される場合は返されるべきではありませんnull...'APIはそれを許可していません...そしてあなたはメッセージを見るでしょう

  • 例外がスローされた場合は、Error: ...メッセージが表示されます

私の結論は、異なるスレッドがアプリケーションを終了させて​​いるか、アプリケーションがまったく終了していないということです。

私が考えることができる他の唯一の説明は、編集/コンパイル/デプロイ/実行手順が機能しておらず、実際に実行されているコードが、使用しているコードと一致していないことです。

他の人がそれを再現して実際に何が起こっているのかを理解できるように、このためのSSCCEを作成することをお勧めします。

于 2013-03-01T14:47:06.830 に答える
0

ここで同じ問題。コードをトレースしましたが、con.getInputStream()で永久にスタックします。問題を再現するには、以下のコード例を実行します。(正しいURLを入力してください)

A)別のホストでHTTPSサーバーを起動します

B)クライアントコードを開始します

C)HTTPSサーバーをシャットダウンします

D)HTTPSサーバーを再起動します

-> con.getInputStream()でスタック

HTTPSサーバーを再起動しているときに、クライアントでデッドロックが発生しているようです。参考までに、バンドルorg.apache.felix.http.jettyをHTTP(S)-Restletサーブレットが接続されたサーバーとして使用しています。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class TestHTTPS{

public static void main(String[] args) throws InterruptedException
{
    new TestHTTPS().activate();
}

private void activate() throws InterruptedException{

    TrustManager[] insecureTrustManager = new TrustManager[] { 
            new X509TrustManager() {     
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                } 
                public void checkClientTrusted( 
                    java.security.cert.X509Certificate[] certs, String authType) {
                    } 
                public void checkServerTrusted( 
                    java.security.cert.X509Certificate[] certs, String authType) {
                }
            } 
        }; 


    try {
        SSLContext sc = SSLContext.getInstance("SSL"); 
        sc.init(null, insecureTrustManager, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (KeyManagementException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } 

    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

    String https_url = "https://192.168.xx.xx:8443";
    URL url;
    try {

        url = new URL(https_url);

        while(true) {
            HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
            con.setConnectTimeout(1000);
            print_content(con);
            Thread.sleep(100);
        }

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

private void print_content(HttpsURLConnection con){
    if(con!=null){

        try {

            System.out.println("****** Content of the URL ********");           
            BufferedReader br = 
                    new BufferedReader(
                            new InputStreamReader(con.getInputStream()));

            String input;

            while ((input = br.readLine()) != null){
                System.out.println(input);
            }
            br.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

任意の推奨事項を歓迎します。

于 2013-07-31T11:53:58.063 に答える
0

修正しました。

con.setReadTimeout(1000)

明らかにHTTPサーバーは接続を受け入れますが、サーバーの起動中に間違ったタイミングで接続すると、要求を満たすことができません。setReadTimeoutにより、スレッドはSocketTimeoutExceptionをスローします。

これが他の誰かが問題を解決するのに役立つことを願っています...

この問題は、内部コネクタでRESTletを使用しているときにも発生する可能性があるため、RESTletの解決策を次に示します。hostnameVerifierとSSLContextFactoryを自分で処理する必要があります。

context = new Context();

context.getParameters().add("readTimeout", Integer.toString(1000));
context.getAttributes().put("sslContextFactory", new YourSslContextFactory());
context.getAttributes().put("hostnameVerifier", new YourHostnameVerifier());

client = new Client(context, Protocol.HTTPS);

確実に

org.restlet.ext.ssl 
org.restlet.ext.net
org.restlet.ext.httpclient 

クラスパスにあります。

よろしくお願いします

于 2013-07-31T14:19:01.177 に答える