2016-02-07 35 views
1

我正在編寫一個模塊,用於使用其新的HTTP提供程序API將推送通知發送到使用APN的IOS設備。但是我在閱讀過程中遇到了一些問題從response.Its拋出以下一個無效的HTTP響應和error.The輸出是一段代碼,我已經寫了:使用其HTTP API打開與APNS的連接時發生無效的Http響應

static SSLSocketFactory getSSLSocketFactory() { 
     try { 
      String keystoreFilename = "D:/Oracle/IDCS/MFA/APNS/OMA_prereqs/iOS_prod.p12"; 
      char[] storepass = "welcome1".toCharArray(); 
      FileInputStream fis = new FileInputStream(
        new File(keystoreFilename)); 

      final KeyStore ks = KeyStore.getInstance("PKCS12"); 
      ks.load(fis, storepass); 

      KeyManagerFactory keyManagerFactory = KeyManagerFactory 
        .getInstance("SunX509"); 
      keyManagerFactory.init(ks, storepass); 

      TrustManagerFactory trustManagerFactory = TrustManagerFactory 
        .getInstance("SunX509"); 
      trustManagerFactory.init((KeyStore) null); 
      // trustManagerFactory.init(ks); 

      // create ssl context 
      SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); 


      // setup the HTTPS context and parameters 
      sslContext.init(keyManagerFactory.getKeyManagers(), 
        trustManagerFactory.getTrustManagers(), null); 

      if (keyManagerFactory != null || trustManagerFactory != null) { 
       return SSLTunnelSocketFactory.wrap(proxy, 
         sslContext.getSocketFactory()); 
      } 
     } catch (Exception e) { 
      System.out.println("Unable to create ssl socket factory"); 
      e.printStackTrace(); 
     } 
     return HttpsURLConnection.getDefaultSSLSocketFactory(); 
    } 

    private static void sendSamplePushNotification() { 
       System.setProperty("javax.net.debug", "all"); 
       URL url = null; 
       try { 
        HostnameVerifier hv = new HostnameVerifier() { 
         public boolean verify(String urlHostName, SSLSession session) { 
          return true; 
         } 
        }; 
        JSONObject payload = new JSONObject(); 
        JSONObject msg = new JSONObject(); 
        try { 
         msg.put("alert", "Hello APNS"); 
         payload.put("aps", msg); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
        url = new URL(
          "https://api.development.push.apple.com:443/3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0"); 
        HttpsURLConnection conn = (HttpsURLConnection) url 
          .openConnection(proxy); 
        conn.setRequestMethod("POST"); 
        conn.setDoOutput(true); 
        conn.setHostnameVerifier(hv); 
        conn.setSSLSocketFactory(getSSLSocketFactory()); 
        /*conn.setRequestProperty("content-length", new String(payload 
          .toString().getBytes()));*/ 
        conn.setConnectTimeout(3000); 
        conn.connect(); 
        OutputStream os = conn.getOutputStream(); 
        OutputStreamWriter writer = new OutputStreamWriter(os); 
        BufferedWriter bw = new BufferedWriter(writer); 
        bw.write(payload.toString()); 
        bw.flush(); 
        //System.out.println("Response code : " + conn.getResponseCode()); 
        System.out.println(conn.getResponseMessage()); 
        InputStream is = conn.getInputStream(); 
        ................ 
      } 

我得到上執行此下列情況除外:

............................. 
    ............................... 
    main, WRITE: TLSv1.2 Alert, length = 26 
[Raw write]: length = 31 
0000: 15 03 03 00 1A 00 00 00 00 00 00 00 04 75 ED 66 .............u.f 
0010: D6 88 EC E2 B4 8F FF A2 7E CC 1C 22 FF A7 EF  ..........."... 
main, called closeSocket(true) 
null 
java.io.IOException: Invalid Http response 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1889) 
    at sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1884) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1883) 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1456) 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) 
    at com.coding.mfa.apns.driver.APNSDriver.sendSamplePushNotification(APNSDriver.java:141) 
    at com.coding.mfa.apns.driver.APNSDriver.main(APNSDriver.java:38) 
Caused by: java.io.IOException: Invalid Http response 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1554) 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440) 
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) 
    at java.net.HttpURLConnection.getResponseMessage(HttpURLConnection.java:546) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseMessage(HttpsURLConnectionImpl.java:382) 
    at com.coding.mfa.apns.driver.APNSDriver.sendSamplePushNotification(APNSDriver.java:140) 
    ... 1 more 

燦有人請幫助我? SSL握手似乎很好。它在線'conn.getInputStream()'失敗'

+0

請添加完整的例外文本。此外,如果您使用調試來確定代碼在代碼中的位置,它將有所幫助。 –

+0

@RoyFalk我已經用完整的異常堆棧跟蹤編輯了這個問題。你能幫我解決嗎?另外一個諷刺的是,從PostMan休息客戶端,我可以成功發送推送通知請求並在我的設備上接收。 –

+0

你有沒有考慮過普希https://relayrides.github.io/pushy/?或者可能使用源代碼作爲靈感.. – Adrian

回答

0

首先,我在我的角色中添加了評論,作爲新問題的評論者。堆棧跟蹤增加了人們想出來的機會。

其次,它會幫助你找到導致崩潰的行,因爲堆棧跟蹤沒有列出你的代碼(可能還有1個?)。請注意,與空指針不同,無效的HTTP響應不一定是您的代碼的問題。這導致我...

第三,和我寫這個作爲答案的原因,用Java它可能是餅乾。嘗試:

CookieManager cookieManager = new CookieManager(); 
CookieHandler.setDefault(cookieManager); 

第四,如果一切都失敗了,你需要弄清楚郵遞員,無論是未來走出的Java代碼之間的差異。 wireshark或類似的工具可能會伎倆。

更新: This崗位上的超級用戶似乎表明Java 7的默認禁用TLS1.2。

我看到你正在發送TLS1.2。如果你使用Java 7,看起來有bug affecting updates 25 and above

+0

它在'InputStream is = conn.getInputStream();'行失敗 –

+0

這是可以預料的。我的意思是你應該把它添加到問題中,因爲在其他情況下,很難判斷堆棧跟蹤何時不完整。你有沒有試過我的建議? –

+0

我已經提到失敗的線以前本身就在它的尾部問題本身。對於你所建議的選項,我已經嘗試了第三種選擇,但我仍然遇到了問題,並在第四個我使用的提琴手調試網絡流量。請求和響應在工具輸出中看起來很好,但我仍然在java代碼中得到相同的錯誤。 –

1

從「APNs Provider API」文檔:「此API基於HTTP/2網絡協議」。 Java目前不支持HTTP/2。預計Java 9會支持HTTP/2。 您需要使用第三方HTTP客戶端,這裏是sugestions:Does Apache or some other CLIENT JAVA implementation support HTTP/2?

+0

感謝Paulo,我在回溯一段時間後找到了答案。無論如何,在我們的項目中,我們繼續使用APNS二進制提供程序API發送通知。 –

相關問題