Java tutorial
/* Copyright (C) 2014 Prasanna Thirumalai This file is part of StackX. StackX is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. StackX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with StackX. If not, see <http://www.gnu.org/licenses/>. */ package com.prasanna.android.http; import java.io.IOException; import java.io.InputStream; 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.util.Map; import java.util.zip.GZIPInputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; 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.conn.ssl.SSLSocketFactory; import org.apache.http.entity.HttpEntityWrapper; 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.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.net.Uri.Builder; import com.prasanna.android.http.ClientException.ClientErrorCode; import com.prasanna.android.stacknetwork.utils.Validate; import com.prasanna.android.utils.LogWrapper; public class SecureHttpHelper { private final String TAG = SecureHttpHelper.class.getSimpleName(); private static final int HTTP_PORT = 80; private static final int HTTPS_PORT = 443; private static final String SCHEME_HTTP = "http"; private static final String SCHEME_HTTPS = "https"; private static final String GZIP = "gzip"; private static final SecureHttpHelper httpHelper = new SecureHttpHelper(); public static final HttpGzipResponseInterceptor HTTP_GZIP_RESPONSE_INTERCEPTOR = new HttpGzipResponseInterceptor( GZIP, GzipDecompressingEntity.class); public interface HttpResponseBodyParser<T> { T parse(String responseBody) throws HttpResponseParseException; } public static class HttpErrorFamily { public static final int CLIENT_ERROR = 400; public static final int SERVER_ERROR = 500; } public static class GzipDecompressingEntity extends HttpEntityWrapper { public GzipDecompressingEntity(final HttpEntity entity) { super(entity); } @Override public InputStream getContent() throws IOException, IllegalStateException { return new GZIPInputStream(wrappedEntity.getContent()); } @Override public long getContentLength() { return -1; } } public static class HttpResponseParseException extends Exception { private static final long serialVersionUID = 8952054677122646195L; public HttpResponseParseException(Throwable throwable) { super(throwable); } } protected SecureHttpHelper() { } public static SecureHttpHelper getInstance() { return httpHelper; } public Bitmap getImage(final String absoluteUrl) { if (absoluteUrl != null) { try { HttpResponse response = createSecureHttpClient().execute(getHttpGetObject(absoluteUrl)); return getBitmap(response); } catch (ClientProtocolException e) { LogWrapper.e(TAG, e.getMessage()); } catch (IOException e) { LogWrapper.e(TAG, e.getMessage()); } throw new ClientException(ClientErrorCode.HTTP_REQ_ERROR); } return null; } public <T> T executeHttpPost(String host, String path, Map<String, String> requestHeaders, Map<String, String> queryParams, HttpEntity httpEntity, HttpResponseInterceptor httpResponseInterceptor, HttpResponseBodyParser<T> responseBodyParser) { HttpPost request = getHttpPostObject(buildUri(host, path, queryParams)); if (requestHeaders != null) { for (Map.Entry<String, String> entry : requestHeaders.entrySet()) request.setHeader(entry.getKey(), entry.getValue()); } if (httpEntity != null) request.setEntity(httpEntity); return executeRequest(getHttpClient(httpResponseInterceptor), request, responseBodyParser); } public <T> T executeHttpGet(String host, String path, Map<String, String> queryParams, HttpResponseInterceptor httpResponseInterceptor, HttpResponseBodyParser<T> responseBodyParser) { HttpGet request = getHttpGetObject(buildUri(host, path, queryParams)); request.setHeader(HttpHeaderParams.ACCEPT, HttpContentTypes.APPLICATION_JSON); return executeRequest(getHttpClient(httpResponseInterceptor), request, responseBodyParser); } private <T> T executeRequest(HttpClient client, HttpRequestBase request, HttpResponseBodyParser<T> responseBodyParser) { LogWrapper.d(TAG, "HTTP request to: " + request.getURI().toString()); try { HttpResponse httpResponse = client.execute(request); HttpEntity entity = httpResponse.getEntity(); String responseBody = EntityUtils.toString(entity, HTTP.UTF_8); int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) return responseBodyParser.parse(responseBody); else { LogWrapper.d(TAG, "Http request failed: " + statusCode + ", " + responseBody); if (statusCode >= HttpErrorFamily.SERVER_ERROR) throw new ServerException(statusCode, httpResponse.getStatusLine().getReasonPhrase(), responseBody); else if (statusCode >= HttpErrorFamily.CLIENT_ERROR) throw new ClientException(statusCode, httpResponse.getStatusLine().getReasonPhrase(), responseBody); } } catch (ClientProtocolException e) { LogWrapper.e(TAG, e.getMessage()); } catch (IOException e) { LogWrapper.e(TAG, e.getMessage()); } catch (HttpResponseParseException e) { throw new ClientException(ClientErrorCode.RESPONSE_PARSE_ERROR, e.getCause()); } return null; } private HttpClient getHttpClient(HttpResponseInterceptor httpResponseInterceptor) { HttpClient client = createSecureHttpClient(); if (httpResponseInterceptor != null) ((DefaultHttpClient) client).addResponseInterceptor(httpResponseInterceptor); return client; } protected HttpClient createSecureHttpClient() { try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); SSLSocketFactory sf = new SSLSocketFactoryX509(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 schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme(SCHEME_HTTPS, sf, HTTPS_PORT)); schemeRegistry.register(new Scheme(SCHEME_HTTP, PlainSocketFactory.getSocketFactory(), HTTP_PORT)); return new DefaultHttpClient(new SingleClientConnManager(params, schemeRegistry), params); } catch (KeyManagementException e) { LogWrapper.e(TAG, e.getMessage()); } catch (UnrecoverableKeyException e) { LogWrapper.e(TAG, e.getMessage()); } catch (KeyStoreException e) { LogWrapper.e(TAG, e.getMessage()); } catch (NoSuchAlgorithmException e) { LogWrapper.e(TAG, e.getMessage()); } catch (CertificateException e) { LogWrapper.e(TAG, e.getMessage()); } catch (IOException e) { LogWrapper.e(TAG, e.getMessage()); } throw new ClientException(ClientErrorCode.HTTP_REQ_ERROR); } protected String buildUri(String host, String path, Map<String, String> queryParams) { Validate.notNull(host, path); Builder uriBuilder = Uri.parse(host).buildUpon().appendPath(path); if (queryParams != null) { for (Map.Entry<String, String> entrySet : queryParams.entrySet()) uriBuilder.appendQueryParameter(entrySet.getKey(), entrySet.getValue()); } return uriBuilder.build().toString(); } protected Bitmap getBitmap(HttpResponse response) throws IOException { return BitmapFactory.decodeStream(response.getEntity().getContent()); } protected HttpGet getHttpGetObject(String absoluteUrl) { return new HttpGet(absoluteUrl); } protected HttpPost getHttpPostObject(String absoluteUrl) { return new HttpPost(absoluteUrl); } protected HttpPut getHttpPutObject(String absoluteUrl) { return new HttpPut(absoluteUrl); } }