4

我正在尝试java.net.HttpURLConnection进行简单的 HTTP GET 调用,但遇到了一些我无法解释的问题:

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() 上。要重现问题,请运行下面的代码示例。(输入正确的网址)

A) 在另一台主机上启动任何 HTTPS 服务器

B) 启动客户端代码

C) 关闭 HTTPS 服务器

D) 再次启动 HTTPS 服务器

-> 卡在 con.getInputStream()

在重新启动 HTTPS 服务器时,客户端似乎发生了一些死锁。仅供参考,我使用捆绑包 org.apache.felix.http.jetty 作为 HTTP(S)-Server 并附加了 Restlet Servlet。

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.getInputStream()当我检查是否为空时,它似乎正在死去。

好吧,我觉得这很难相信。

从表面上看:

  • 测试引用以查看它是否null无法终止您的程序

  • 可以con.getInputStream()抛出异常或返回

  • 如果确实返回它不应该返回null......'因为 API 不允许它......你会看到一条消息

  • 如果抛出异常,您会看到Error: ...消息

我的结论是,要么不同的线程导致应用程序退出,要么应用程序根本没有退出。

我能想到的唯一其他解释是您的编辑/编译/部署/运行过程不起作用,并且实际运行的代码与您显示使用的代码不匹配。

我建议您尝试为此创建一个SSCCE,以便其他人可以重现它并找出实际发生的情况。

于 2013-03-01T14:47:06.830 回答
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 回答