开发者

POST over SSL/HTTPS REST Api Android is responding 400 Bad Request

In my application I want to post from my android application XML data in the remote server which is using REST service. My code is below:

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

But that server is behind SSL/HTTPS protocol so i am getting the below 400 Bad Request as response.

<!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>

If I use SSLSocketFactory like below

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

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

I got exception

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

at line

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

My question is, how can i post the data over SSL from android application in my above scenario? I guess many of us are facing this problem, so I am requesting you to give me/us some elaborated answers.Cheers.


Too many unknowns :-)

Try plain HTTP against a test server you have control over. My hunch is it will give the same error. You don't seem to put an empty line between the HTTP headers and body for example.

Why are you re-implementing HTTP anyway? Don't tell me there's no API or library you could use on whatever platform this is? Usually there's java.net.HttpUrlConnection, or Apache HttpClient.

Edit:

Hey, look what google brought in: http://developer.android.com/reference/android/net/http/AndroidHttpClient.html


It seems that I needed to add the TrustAnchor certificate to be able to validate the whole key chain. I have requested about this certificate to my API Provider and they given me the web link from where I can get the certificate. [i have changed the web link for confidentiality]

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

They also told me to get try the connection via (i guess it should be executed from command prompt)

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

I then have to integrate the certificate into my application.

I will now try to know how can I integrate that certificate, but that discussion should be in another question.


I have done it. The code is given below.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜