2011-07-12 6 views
0

私のアプリケーションでは、RESTサービスを使用しているリモートサーバーのAndroidアプリケーションXMLデータから投稿します。POST over SSL/HTTPS REST Api Androidが応答していません400 Bad Request

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> 

私は

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

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

以下のようなのSSLSocketFactoryを使用している場合は、私は私の質問は、私がデータを投稿することができますどのように、あるライン

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

で例外

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

を得ましたSSL経由で私の上記のシナリオでは、Androidアプリケーションですか? 私たちの多くはこの問題に直面していると思いますので、私はあなたに私/私たちにいくつか精巧な答えを与えるように依頼しています。

答えて

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があります。

編集:

ねえ、Googleがもたらしたものを見て: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/where -do-i-put-the-rest-client-authentication-data-in-the-query –

0

私が全体のキーチェーンを検証できるようにするのTrustAnchor証明書を追加する必要があると思われます。 私はAPIプロバイダに対してこの証明書を要求しており、証明書を入手できる場所からWebリンクを取得しました。彼らはまた、(私はそれは、コマンドプロンプトから実行する必要がありますね)

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

私は、持っている経由で接続を試みる取得するために私に言った

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

[私は、機密性のためのWebリンクを変更しました]証明書を自分のアプリケーションに統合する。

ここで、その証明書をどのように統合できるかを知ろうとしますが、その議論は別の質問になるはずです。

関連する問題