POST через SSL / HTTPS REST Api Android отвечает 400 неправильных запросов - PullRequest
0 голосов
/ 12 июля 2011

В моем приложении я хочу отправить из моего приложения Android данные XML на удаленный сервер, который использует сервис REST.Мой код приведен ниже:

 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 Bad Request.

<!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?в моем приведенном выше сценарии? Я полагаю, что многие из нас сталкиваются с этой проблемой, поэтому я прошу вас дать мне / нам некоторые подробные ответы. Приветствия.

Ответы [ 3 ]

1 голос
/ 12 июля 2011

Слишком много неизвестных: -)

Попробуйте простой HTTP на тестовом сервере, которым вы управляете. Я догадываюсь, что это даст ту же ошибку. Вы, кажется, не помещаете пустую строку между заголовками HTTP и body, например.

Почему вы все-таки повторно используете HTTP? Не говорите мне, что нет API или библиотеки, которую вы могли бы использовать на любой платформе? Обычно это java.net.HttpUrlConnection или Apache HttpClient.

Edit:

Эй, посмотри, что принес Google: http://developer.android.com/reference/android/net/http/AndroidHttpClient.html

0 голосов
/ 08 августа 2011

Я сделал это. Код приведен ниже.

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();
            }
        }
    }
0 голосов
/ 14 июля 2011

Кажется, мне нужно было добавить сертификат TrustAnchor , чтобы иметь возможность проверить всю цепочку ключей. Я запросил об этом сертификате моего провайдера API, и они дали мне веб-ссылку, откуда я могу получить сертификат. [Я изменил веб-ссылку для конфиденциальности]

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

Они также сказали мне попробовать подключиться через (я думаю, это должно быть выполнено из командной строки)

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

Затем я должен интегрировать сертификат в свое приложение.

Теперь я попытаюсь узнать, как я могу интегрировать этот сертификат, но это обсуждение должно быть в другом вопросе.

...