2013-03-01 3 views
4

나는 간단한 HTTP의 GET 통화를 할 java.net.HttpURLConnection를 사용하려고 내가 설명 할 수없는 무언가로 실행하고 있습니다 :자바 HttpURLConnection의 죽어가는 신비

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 

그리고 오류없이 프로그램이 종료됩니다. 예외가 발생하지 않고 예기치 않게 종료되지 않고 중단되거나 시간 초과되지 않고 그냥 죽게됩니다.

null 인 경우 con.getInputStream()을 확인하면 죽어가는 것 같습니다. 그러나 그것은 아직도 오류의 징조없이 조용히 죽는 이유를 설명하지 못합니다. 어떤 아이디어? 나는 내가 HttpURLConnection을 잘못 만들 수 있음을 인정하지만 여전히 내 프로그램을 죽이는 것에 대한 더 많은 표시가 있어야합니다 ... 미리 감사드립니다!

+0

분명히하지만 앱을 청소하고 다시 컴파일 해보십시오. –

+0

이것이 코드의 버그라고 생각하지 않습니다. 프로젝트와 관련이 있어야합니다. 명령 줄이나 IDE에있는 경우 새 프로젝트에서 실행 해보십시오. –

+0

프로젝트를 정리하고 Eclipse를 다시 시작한 후 다시 컴파일했습니다. 여전히 동일합니다. 이것이 프로젝트와 관련이 있다고 생각하는 이유는 무엇이며 근본적인 문제의 원인은 무엇입니까? 다시 한 번 감사드립니다! – IAmYourFaja

답변

0

con.getInputStream()이 Null인지 여부를 확인하면 죽어가는 것 같습니다.

글쎄 나는 믿기 어렵다. 그것의 얼굴에

는 : 그것은 nullcon.getInputStream()가 예외를 던지거나

  • 경우를 반환 할 수 있습니다

  • 프로그램 종료 할 수없는 경우

    • 은보고 참조를 테스트 반환하지 않아야합니다. null ... 'API가 허용하지 않기 때문에 ... 메시지가 표시됩니다.

    • 예외가 발생 된 경우
    • 당신은

    내 결론은 하나 다른 스레드 응용 프로그램이 종료의 원인이되는, 또는 응용 프로그램이 전혀 나오지 않는 있다는 것입니다 Error: ... 메시지를 볼 것입니다.

    내가 생각할 수있는 유일한 다른 설명은 편집/컴파일/배포/실행 절차가 작동하지 않고 실제로 실행중인 코드가 사용중인 코드와 일치하지 않는다는 것입니다.

    다른 사람들이 그것을 재현하고 실제로 무슨 일이 일어나고 있는지 파악할 수 있도록 이것을 위해 SSCCE을 만들 것을 제안합니다.

  • 1

    코드는이 라인부터 컴파일하면 안

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

    누락 된 세미콜론이있다. 그 말로는, 당신이 사용하고있는 응용 프로그램의 실행이 이전 실행을 사용하고 있으며 아마 작성한 새 코드가 없다고 생각합니다.

    그런 경우가 아니라면 (어떤 식 으로든) 코드를 잘못 붙여 넣었고 우리가 볼 필요가있는 다른 부분을 놓쳤다 고 추측 할 수 있습니까? StackOverflow를 위해 코드를 편집 한 적이 있다면 원본을 공유 하시겠습니까?

    또한 이유가없는 한 Throwable을 잡는 것에 대해 권할 것입니다. 일반적으로 애플리케이션 오류를 마스크하는 것은 좋지 않습니다.

    0

    같은 문제가 여기에 있습니다. 내 코드를 추적하면 con.getInputStream()에서 영원히 멈추게됩니다. 문제를 재현하려면 아래 코드 예제를 실행하십시오. 다시 시작)

    A) 다른 호스트에

    B를 어떤 HTTPS 서버를 시작

    를 클라이언트 코드

    C) 종료 HTTPS 서버

    D) 시작 HTTPS 서버 (올바른 URL을 넣어)

    -> con.getInputStream()에서 멈춤

    HTTPS 서버를 다시 시작하는 동안 클라이언트에서 일부 교착 상태가 발생하는 것처럼 보입니다. 참고 : Restlet Servlet이 첨부 된 HTTP (S) -Server 번들로 org.apache.felix.http.jetty 번들을 사용하고 있습니다.

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

    모든 권장 사항을 환영합니다.

    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 
    

    이 클래스 경로에합니다.

    최고 감사합니다.