Introduction
In this article I have discussed the procedure to
request HTTP and HTTPS requests in android. In mobiles, most of applications
based on client server communication through HTTP or HTTPS protocol, so it is
essential for a small or a large sized application that your HTTP module
follows the complete object oriented and has a separate coupled module from other
package of application.
Focus in this article is that an only single
class handles both types of request (HTTP and HTTPS), normally developers
handle the HTTP and HTTPS
in two different classes, but in this in potent interest, I have handled
it in a single class. Developer will need to invoke a class and implement a
listener for getting the response as a notification.
Background
Steps involved:
String urlString = "HTTP://www.google.com";
List<NameValuePair> requestParameter= new
List<NameValuePair>();
NameValuePair namVaulePair = new
NameValuePair("name","ravindra");
requestParameter .add(namVaulePair);
int reqId = 100;
HTTPHandler handler = new HTTPHandler(urlString, requestParameter,null,reqId);
Handler.addHTTPListenr(‘reference of that class implement HTTPListener’);
Hdler.sendRequest();
Using the code
There are five classes in this demo project, divided
into two packages one is UI package there from you enter URL and tap on request
button and send request.
HTTPHandler: This class handles the request of HTTP:
HTTPHandler(String urlstring, final List<NameValuePair> requestParameters,final
Hashtable<String, String> header, int reqId)
User
: first call the constructor and pass required parameter.
urlStirng
: URL for HTTP request for example ‘HTTP://www.google.com’
requestParameters
: if request method types is ‘POST’ then user set the list of parameters in form of NameValuePair otherwise It should be null if request method type is ‘GET’.
header
: it contain the header you want to set in
each HTTP request.
reqId : unique identifier of HTTP request.
getReqID()
: it return the unique request id which
used in HTTP request.
getURL()
: return the URL used in HTTP request.
getResponse()
: return the response return by
requested server.
getResCode()
: it return the HTTP status line. If
return 200 then request is successful another wise it fail due to server reason.
Or invalid request by client.
addHTTPListener
:
add the concrete class which implement the HTTPListener class and
override notifyResponse()
for handle response return by server.
sendRequest()
:
this method execute the HTTP request.
HTTPHandler class code:
package com.brickred.HTTP;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import org.apache.HTTP.HTTPEntity;
import org.apache.HTTP.HTTPResponse;
import org.apache.HTTP.HTTPVersion;
import org.apache.HTTP.NameValuePair;
import org.apache.HTTP.client.ClientProtocolException;
import org.apache.HTTP.client.HTTPClient;
import org.apache.HTTP.client.ResponseHandler;
import org.apache.HTTP.client.entity.UrlEncodedFormEntity;
import org.apache.HTTP.client.methods.HTTPGet;
import org.apache.HTTP.client.methods.HTTPPost;
import org.apache.HTTP.conn.ClientConnectionManager;
import org.apache.HTTP.conn.params.ConnManagerPNames;
import org.apache.HTTP.conn.params.ConnPerRouteBean;
import org.apache.HTTP.conn.scheme.PlainSocketFactory;
import org.apache.HTTP.conn.scheme.Scheme;
import org.apache.HTTP.conn.scheme.SchemeRegistry;
import org.apache.HTTP.entity.StringEntity;
import org.apache.HTTP.impl.client.DefaultHTTPClient;
import org.apache.HTTP.impl.conn.SingleClientConnManager;
import org.apache.HTTP.params.BasicHTTPParams;
import org.apache.HTTP.params.CoreConnectionPNames;
import org.apache.HTTP.params.HTTPParams;
import org.apache.HTTP.params.HTTPProtocolParams;
import org.apache.HTTP.util.EntityUtils;
import android.content.Context;
import android.util.Log;
public class HTTPHandler {
HTTPListner HTTPListener;
String urlstring = "";
List<NameValuePair> postRequestParameters = null;
int reqId = 0;
String resMessage = "No Response Please check Url or it may be HTTPS certificate issue.";
int resCode = -1;
Hashtable<String, String> header = null;
public HTTPHandler(String urlstring,
final List<NameValuePair> requestParameters,
final Hashtable<String, String> header, int reqId) {
this.urlstring = urlstring;
this.postRequestParameters = requestParameters;
this.reqId = reqId;
this.header = header;
}
public int getReqId() {
return reqId;
}
public String getURL() {
return urlstring;
}
public String getResponse() {
return resMessage;
}
public int getResCode() {
return resCode;
}
public void addHTTPLisner(HTTPListner HTTPListener) {
this.HTTPListener = HTTPListener;
}
public void sendRequest() {
try {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("HTTP", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("HTTPS", new EasySSLSocketFactory(), 443));
HTTPParams params = new BasicHTTPParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 50000);
params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
params.setParameter(HTTPProtocolParams.USE_EXPECT_CONTINUE, false);
HTTPProtocolParams.setVersion(params, HTTPVersion.HTTP_1_1);
ClientConnectionManager cm = new SingleClientConnManager(params, schemeRegistry);
HTTPClient HTTPclient = new DefaultHTTPClient(cm, params);
if (postRequestParameters != null) {
HTTPPost HTTPpost = new HTTPPost(urlstring);
if (header != null) {
Enumeration enums = header.keys();
while (enums.hasMoreElements()) {
String key = (String) enums.nextElement();
String value = header.get(key);
HTTPpost.addHeader(key, value);
}
}
HTTPpost.setEntity(new UrlEncodedFormEntity(postRequestParameters));
ResponseHandler<String> reshandler = new ResponseHandler<String>() {
public String handleResponse(HTTPResponse response)
throws ClientProtocolException, IOException {
HTTPEntity entity = response.getEntity();
resCode = response.getStatusLine().getStatusCode();
StringBuffer out = new StringBuffer();
byte[] b = EntityUtils.toByteArray(entity);
out.append(new String(b, 0, b.length));
return out.toString();
}
};
resMessage = HTTPclient.execute(HTTPpost, reshandler);
}
else {
ResponseHandler<String> responsehandler = new ResponseHandler<String>() {
@Override
public String handleResponse(HTTPResponse response)
throws ClientProtocolException, IOException {
HTTPEntity entity = response.getEntity();
resCode = response.getStatusLine().getStatusCode();
StringBuffer out = new StringBuffer();
byte[] b = EntityUtils.toByteArray(entity);
out.append(new String(b, 0, b.length));
return out.toString();
}
};
HTTPGet HTTPget = new HTTPGet(urlstring);
resMessage = HTTPclient.execute(HTTPget, responsehandler);
}
HTTPclient.getConnectionManager().shutdown();
}
catch (Exception e) {
Log.i("connection Exeception", e.getMessage());
}
finally {
HTTPListener.notifyHTTPRespons(this);
}
}
}
HTTPListener: This listener must be implement and
override the single abstract method notifyResponse()
for get the response generated by HTTP request and know the status of request.
Code:
package com.brickred.HTTP;
public interface HTTPListner {
void notifyHTTPRespons(HTTPHandler HTTP);
}
EasySSlSocketFactory
: This socket factory class will create the self signed certificate.
package com.testHTTPS;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import org.apache.HTTP.conn.ConnectTimeoutException;
import org.apache.HTTP.conn.scheme.LayeredSocketFactory;
import org.apache.HTTP.conn.scheme.SocketFactory;
import org.apache.HTTP.params.HTTPConnectionParams;
import org.apache.HTTP.params.HTTPParams;
public class EasySSLSocketFactory implements SocketFactory, LayeredSocketFactory {
private SSLContext sslcontext = null;
private static SSLContext createEasySSLContext() throws IOException {
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null);
return context;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
private SSLContext getSSLContext() throws IOException {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
public Socket connectSocket(Socket sock, String host, int port, InetAddress localAddress, int localPort, HTTPParams params)
throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HTTPConnectionParams.getConnectionTimeout(params);
int soTimeout = HTTPConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
if (localPort < 0) {
localPort = 0;
}
InetSocketAddress isa = new InetSocketAddress(localAddress, localPort);
sslsock.bind(isa);
}
sslsock.connect(remoteAddress, connTimeout);
sslsock.setSoTimeout(soTimeout);
return sslsock;
}
public Socket createSocket() throws IOException {
return getSSLContext().getSocketFactory().createSocket();
}
public boolean isSecure(Socket socket) throws IllegalArgumentException {
return true;
}
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
}
public int hashCode() {
return EasySSLSocketFactory.class.hashCode();
}
}
Class EasyX509TrustManager code:
package com.brickred.HTTP;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class EasyX509TrustManager
implements X509TrustManager
{
private X509TrustManager standardTrustManager = null;
public EasyX509TrustManager( KeyStore keystore )
throws NoSuchAlgorithmException, KeyStoreException
{
super();
TrustManagerFactory factory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm() );
factory.init( keystore );
TrustManager[] trustmanagers = factory.getTrustManagers();
if ( trustmanagers.length == 0 )
{
throw new NoSuchAlgorithmException( "no trust manager found" );
}
this.standardTrustManager = (X509TrustManager) trustmanagers[0];
}
public void checkClientTrusted(X509Certificate[] certificates, String authType )
throws CertificateException
{
standardTrustManager.checkClientTrusted( certificates, authType );
}
public void checkServerTrusted(X509Certificate[] certificates, String authType )
throws CertificateException
{
if ( ( certificates != null) && ( certificates.length == 1 ) )
{
certificates[0].checkValidity();
}
else
{
standardTrustManager.checkServerTrusted( certificates, authType );
}
}
public X509Certificate[] getAcceptedIssuers()
{
return this.standardTrustManager.getAcceptedIssuers();
}
}
AndroidManifest.xml
="1.0"="utf-8"
<manifest xmlns:android="HTTP://schemas.android.com/apk/res/android"
package="com.brickred"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="com.brickred.activity.HTTPConnectionApiActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
HTTPConnectionApiActivity.java
package com.brickred.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.brickred.R;
import com.brickred.HTTP.HTTPHandler;
import com.brickred.HTTP.HTTPListner;
public class HTTPConnectionApiActivity extends Activity implements HTTPListner{
Handler handler = null;
TextView textviewResponse;
ProgressDialog progressDialog;
EditText edtTextUrl = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonClickMe = (Button)findViewById(R.id.btnclick);
textviewResponse= (TextView)findViewById(R.id.txtshow);
edtTextUrl= (EditText)findViewById(R.id.txturl);
handler = new Handler();
progressDialog = new ProgressDialog(this);
buttonClickMe.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(edtTextUrl.getText().length() > 0 && edtTextUrl.getText().toString().startsWith("HTTP")){
progressDialog.setMessage("Please wait for response ... ");
progressDialog.show();
new Thread(new Runnable() {
@Override
public void run() {
HTTPHandler handler = new HTTPHandler(edtTextUrl.getText().toString().trim(),null, null, 123);
handler.addHTTPLisner(HTTPConnectionApiActivity.this);
handler.sendRequest();
}
}).start();
}else{
showAlert("Error", "Please enter valid url", null, "Ok");
}
}
});
}
@Override
public void notifyHTTPRespons(final HTTPHandler HTTP) {
progressDialog.cancel();
Log.i("Log", "responce == "+HTTP.getResCode());
handler.post(new Runnable() {
@Override
public void run() {
textviewResponse.setText("");
textviewResponse.setText(HTTP.getResponse());
}
});
}
private void showAlert(String title,String Message, final String NegButton,
final String posButton) {
AlertDialog.Builder alertBuilder = new Builder(this);
alertBuilder.setTitle(title);
alertBuilder.setMessage(Message);
if (NegButton != null) {
alertBuilder.setNegativeButton(NegButton,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
}
if (posButton != null) {
alertBuilder.setPositiveButton(posButton,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
}
AlertDialog alert = alertBuilder.create();
alert.show();
}
}
Points of Interest
Interesting point in this article is user no need to write a difference code for HTTP and HTTPS protocol.
User need only just enter the the URL as per as his/her requirement and send the request and its works on multithreading environment.
User can send multiple request at that same time without waiting the previous request completion.