2011-07-12 37 views
0

在我的應用我想從遠程服務器,使用REST服務我的Android應用程序的XML數據發佈。我的代碼如下:POST通過SSL/HTTPS REST API Android是響應400錯誤的請求

String url = "api.example.com"; 
    int port = 443; 
    String query = "<?xml version='1.0' encoding='UTF-8'?><request><client><name>APIappDevAccount</name><password>123456</password></client><user><name>foyzulkarim</name><password>123456</password><groupId>12345</groupId></user></request>"; 
    Socket socket = null; 
    try { 
    socket = new Socket(url,port); 
    } catch (UnknownHostException e2) { 
       // TODO Auto-generated catch block 
       e2.printStackTrace(); 
      } catch (IOException e2) { 
       // TODO Auto-generated catch block 
       e2.printStackTrace(); 
      } 
    BufferedReader br = null; 
      try { 
       br = new BufferedReader(new InputStreamReader(socket.getInputStream()));       
      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
      PrintStream pw = null; 
      try { 
       pw = new PrintStream(socket.getOutputStream()); 

      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      pw.print("POST api.example.com/rest/rest/user"); 
    pw.print("Content-Type: application/xml"); 
      pw.print("Content-Length:" + query.length()); 
      pw.print(query); 
      System.out.println("hello foysal."); 
      //get result 
      String l = null; 
      String text=""; 

      try { 
       while ((l=br.readLine())!=null) { 
        System.out.println(l); 
      text+=l;   
       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      pw.close(); 
      try { 
       br.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

但該服務器是在SSL/HTTPS協議後面,所以我得到了低於400的錯誤請求作爲響應。

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>400 Bad Request</title></head><body><h1>Bad Request</h1><p>Your browser sent a request that this server could not understand.<br />Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />Instead use the HTTPS scheme to access this URL, please.<br /><blockquote>Hint: <a href="https://api.example.com/"><b>https://api.example.com/</b></a></blockquote></p></body></html> 

如果我使用的SSLSocketFactory像下面

SocketFactory socketFactory = SSLSocketFactory.getDefault(); 
    Socket socket = null; 

    try { 
     socket = socketFactory.createSocket(url, port); 

我在行有例外

javax.net.ssl.SSLException: Not trusted server certificate 
java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found. 

br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

我的問題是,我怎麼能發佈數據通過SSL來回在我的上述場景中的Android應用程序? 我想我們很多人都面臨這樣的問題,所以我請求你給我/我們一些闡述answers.Cheers。

回答

0

我都做到了。代碼如下。

private String executeRequest(String targetURL, final String requestMethod, 
      String soap_request_message_header, String soap_request_message_body) { 
     URL url; 
     HttpURLConnection connection = null; 
     try { 
      url = new URL(targetURL); 
      connection = (HttpURLConnection) url.openConnection(); 
      connection.setRequestMethod(requestMethod); 

      connection.setRequestProperty("SOAPAction", 
        soap_request_message_header); 

      connection.setUseCaches(false); 
      connection.setDoInput(true); 
      connection.setDoOutput(true); 

      // Send request 
      DataOutputStream wr = new DataOutputStream(connection 
        .getOutputStream()); 
      wr.writeBytes(soap_request_message_body); 
      wr.flush(); 
      wr.close(); 

      // Get Response 
      InputStream is; 
      final int responseCode = connection.getResponseCode(); 
      Log.i("response", "code=" + responseCode); 
      if (responseCode <= 400) { 
       is = connection.getInputStream(); 
      } else { 
       /* error from server */ 
       is = connection.getErrorStream(); 
      } 
      // is= connection.getInputStream(); 
      BufferedReader rd = new BufferedReader(new InputStreamReader(is)); 
      String line; 
      StringBuffer response = new StringBuffer(); 
      while ((line = rd.readLine()) != null) { 
       response.append(line); 
       response.append('\r'); 
      } 
      rd.close(); 
      Log.i("response", "" + response.toString()); 
      return response.toString(); 

     } catch (Exception e) { 

      Log.e("error https", "", e); 
      return e.getMessage(); 

     } finally { 

      if (connection != null) { 
       connection.disconnect(); 
      } 
     } 
    } 
1

太多的未知:-)

嘗試純HTTP攻擊你能控制的測試服務器。 我的預感是它會給出同樣的錯誤。 例如,您似乎不在HTTP標頭和正文之間放置一條空行。

你爲什麼要重新實現呢HTTP?不要告訴我,你可以在任何平臺上使用API​​或庫嗎?通常有java.net.HttpUrlConnection或Apache HttpClient。

編輯:

嘿,看什麼谷歌帶來了:http://developer.android.com/reference/android/net/http/AndroidHttpClient.html

+0

如果我使用HttpClient,我找不到任何關於刪除或更新命令的例子。更重要的是,發佈xml是api的主要要求。 –

+0

服務是否通過普通HTTP接受您的請求? 400個錯誤的請求表明SSL可以正常工作,但是您的手工製作的HTTP格式不正確。 PrintStream。打印甚至用換行符終止每個頭?我仍然建議使用Apache HttpClient,因爲它似乎已經在您的平臺上可用,而不會增加應用程序的佔用空間。它支持比我知道的更多的方法:http://hc.apache.org/httpclient-3.x/methods.html – Szocske

+0

我想要的是在線程http://stackoverflow.com/questions/6571480/中詳細闡述-do -i-put-the-rest-client-authentication-data-in-the-query –

0

看來,我需要添加TrustAnchor的證書能夠驗證整個鑰匙鏈。 我已經向我的API提供商請求了關於此證書的信息,並且他們給了我從哪裏獲得證書的網頁鏈接。 [我已經改變了網頁鏈接,保密]

https://www.example.com/library/......SSL_bundle.pem

他們還告訴我得到嘗試通過連接(我猜應該從命令提示符下執行)

openssl s_client -connect api.example.com:443 -CAfile /root/SSL_bundle.pem 

然後我有將證書集成到我的應用程序中。

現在我會盡量知道如何集成了證書,但這種討論應該是另外一個問題。

相關問題