Yesterday, i have done an piratical test for an interview. The task provided is to post a username and password to an https url and also to get the response results using an https connection in another url. I have successfully completed the task, but it took me around five hours. I wasted lot of time in researching on how to do an https post. Therefore i thought i could share some of the important information, so that it will we helpful for some one. please not i am not going to share the entire solution.
First create an custom socket factory inside your package. Use the below code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
package baman.lankahomes.lk.zupportdesk; /** * Created by baman on 6/13/16. */ import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.ssl.SSLSocketFactory; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class MySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } @Override public Socket createSocket() throws IOException { return sslContext.getSocketFactory().createSocket(); } } |
Add this function inside your MainActivity class to create a httpClient using custom socket factory. As shown in the below code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public HttpClient getNewHttpClient() { try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", sf, 443)); ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); return new DefaultHttpClient(ccm, params); } catch (Exception e) { return new DefaultHttpClient(); } } |
Then Run an Async task for https post like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
//Async tak to UserToken class getToken extends AsyncTask<String, Void, String> { protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Please wait. Logging in..."); pDialog.show(); } @Override protected String doInBackground(String... arg0) { try { //Post Username and password HttpClient httpclient = getNewHttpClient(); HttpPost httppost = new HttpPost(BASEURL); List<BasicNameValuePair> nameValuePairs = new ArrayList<>(1); nameValuePairs.add(new BasicNameValuePair("Email", arg0[0])); nameValuePairs.add(new BasicNameValuePair("Password", arg0[1])); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); // Execute HTTP Post Request HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, "UTF-8"); pDialog.dismiss(); Log.d("Results ", "tryLogin: "+responseString); return responseString; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } |
And if you want to do an https Get request. See the code below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
class getUserToken extends AsyncTask<String, Void, String> { protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(Profile.this); pDialog.setMessage("Please wait. Loading data..."); pDialog.show(); } @Override protected String doInBackground(String... arg0) { try { // get user token HttpClient httpclient = getNewHttpClient(); HttpGet httpget = new HttpGet(BASEURL); // Execute HTTP get Request HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, "UTF-8"); pDialog.dismiss(); Log.d("Results ", "get login : "+responseString); return responseString; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } |
Hope this helps. Feel free to ask any question if you have in the comments section below.Tnx, Happy coding 🙂