Android Open Source - lightbox-android-webservices Http Helper






From Project

Back to project page lightbox-android-webservices.

License

The source code is released under:

Apache License

If you think the Android project lightbox-android-webservices listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright (c) 2012 Lightbox//ww  w .j a v a 2 s. c  o  m
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lightbox.android.network;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
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.HttpUriRequest;
import org.apache.http.conn.params.ConnManagerParams;
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.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

import android.net.Uri;

import com.lightbox.android.utils.AndroidUtils;
import com.lightbox.android.utils.debug.DebugLog;

/** 
 * HttpHelper 
 * @author Fabien Devos
 */
public class HttpHelper {
  /** Used to tag logs */
  //@SuppressWarnings("unused")
  private static final String TAG = "HttpHelper";
  
  private static final int HTTP_TIMEOUT = 30 * 1000; // 30 sec
  private static final int SOCKET_BUFFER_SIZE = 8 * 1024; // 8 Ko
  private static final String STRING_HTTP = "http";
  private static final String STRING_HTTPS = "https";
  private static final String USER_AGENT_FORMAT_STRING = "%s/%s (Android %s; %s)";
  
  private DefaultHttpClient mHttpClient = null;
  
  /** Used to select an HTTP method. */ 
  public enum HttpMethod {
    GET,
    PUT,
    POST,
    DELETE;
    public HttpUriRequest createHttpRequest(URI uri) {
      switch(this) {
        case GET:
          return new HttpGet(uri);
        case PUT:
          return new HttpPut(uri);
        case POST:
          return new HttpPost(uri);
        case DELETE:
          return new HttpDelete(uri);
      }
      throw new IllegalArgumentException(String.format("Unknown Http Method: %s.", this.toString()));
    }
  }
  
  //----------------------------------------------------------------------------
  // Singleton pattern
  private HttpHelper() {
        mHttpClient = createHttpClient();
  }

  /** HttpHelperHolder is loaded on the first execution of HttpHelper.getInstance() 
   * or the first access to HttpHelperHolder.INSTANCE, not before. */
  private static class HttpHelperHolder {
    private static final HttpHelper INSTANCE = new HttpHelper();
  }

  /** @return a unique instance of the class */
  public static HttpHelper getInstance() {
    return HttpHelperHolder.INSTANCE;
  }

  /** Not supported
   * @throws CloneNotSupportedException (every time) */
  public Object clone() throws CloneNotSupportedException {
    // to prevent any kind of cheating
    throw new CloneNotSupportedException();
  }
  //----------------------------------------------------------------------------
  
  /**
   * Create an HttpClient.
   * @return a properly set HttpClient
   */
  private static DefaultHttpClient createHttpClient() {
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme(STRING_HTTP, PlainSocketFactory.getSocketFactory(), 80));
    schemeRegistry.register(new Scheme(STRING_HTTPS, SSLSocketFactory.getSocketFactory(), 443));
    HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
    HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
    ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
    HttpConnectionParams.setSocketBufferSize(params, SOCKET_BUFFER_SIZE);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
        HttpProtocolParams.setHttpElementCharset(params, HTTP.UTF_8);
    HttpProtocolParams.setUserAgent(params, String.format(USER_AGENT_FORMAT_STRING,
        AndroidUtils.getApplicationLabel(),
        AndroidUtils.getVersionCode(),
        android.os.Build.VERSION.RELEASE,
        android.os.Build.MODEL));
        
    DefaultHttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, schemeRegistry), params);
    enableGzipCompression(client);
    return client;
  }
  
  /**
   * Set Http Basic Authentication. 
   * @param hostname
   * @param username
   * @param password
   */
  public void setBasicAuth(String hostname, String username, String password) {
    if (hostname != null && username != null && password != null) {
      mHttpClient.getCredentialsProvider().setCredentials(
          new AuthScope(hostname, 443, AuthScope.ANY_REALM),
          new UsernamePasswordCredentials(username, password));
      mHttpClient.getCredentialsProvider().setCredentials(
        new AuthScope(hostname, 80, AuthScope.ANY_REALM),
        new UsernamePasswordCredentials(username, password));
    }
  }

  //-------------------------------------------------------------------------------------------
  // HTTP Methods call
  
  /**
   * Call the specified {@link HttpMethod}.
   * Convenience method for {@link #call(HttpMethod, URI, Map, Object, Map)}.
   * @see #call(HttpMethod, URI, Map, Object, Map)
   */
    public HttpResponse call(HttpMethod method, URI uri, Map<String, Object> urlParameters) throws IOException {
    return call(method, uri, urlParameters, null);
    }
    
  /**
   * Call the specified {@link HttpMethod}.
   * Convenience method for {@link #call(HttpMethod, URI, Map, Object, Map)}.
   * @see #call(HttpMethod, URI, Map, Object, Map)
   */
    public HttpResponse call(HttpMethod method, URI uri, Map<String, Object> urlParameters, Object body) throws IOException {
    return call(method, uri, urlParameters, body, null);
    }
  
  /**
   * Call the specified {@link HttpMethod}.
   * @param method
   * @param uri
   * @param urlParameters Optional.
   * @param body Optional. If you pass a Map, it will be passed as Form-URLEncoded, if you pass an {@link HttpEntity}
   * it will be used directly, otherwise the toString will be used.
   * @param headers Optional.
   * @return the {@link HttpResponse}
   * @throws IOException if the request cannot be sent.
   */
    public HttpResponse call(HttpMethod method, URI uri, Map<String, Object> urlParameters, Object body, Map<String, String> headers) throws IOException {
  
      // Add query parameters
      uri = addQueryParametersToUri(uri, urlParameters);
            
        // Create the http request
      HttpUriRequest httpRequest = method.createHttpRequest(uri);

      // Add body
      httpRequest = addBodyToHttpRequest(httpRequest, body);
      
      // Set language
      httpRequest.setHeader("Accept-Language", Locale.getDefault().toString().replace('_', '-'));
      
        // Set headers
        if(headers != null) {
            for(Map.Entry<String, String> header : headers.entrySet()) {
                httpRequest.setHeader(header.getKey(), header.getValue());
            }
        } 
        
        // Send the request
        DebugLog.d(TAG, "Calling %s", uri.toString());
        HttpResponse httpResponse = mHttpClient.execute(httpRequest);

        // Check for redirect
        final int statusCode = httpResponse.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY || statusCode == HttpStatus.SC_MOVED_PERMANENTLY) {
            Header locationHeader = httpResponse.getFirstHeader("Location");
            if (locationHeader != null) {
                String newUrl = locationHeader.getValue();
                // call again with new URL
                return call(method, URI.create(newUrl), urlParameters, body, headers);
            } 
        }
        
        // return a httpResponse
        return httpResponse; 
    }
      
    private static URI addQueryParametersToUri(URI uri, Map<String, Object> urlParameters) {
      if (urlParameters != null && urlParameters.size() > 0) {
        Uri androidUri = Uri.parse(uri.toString());
        Uri.Builder uriBuilder = androidUri.buildUpon();
        for (Map.Entry<String, Object> param : urlParameters.entrySet()) {
            uriBuilder.appendQueryParameter(param.getKey(), param.getValue().toString());
      }
        uri = URI.create(uriBuilder.build().toString());
      }
      return uri;
    }
    
    private static HttpUriRequest addBodyToHttpRequest(HttpUriRequest request, Object body) throws IOException {
      if (body != null && request instanceof HttpEntityEnclosingRequest) {
        HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) request;
        
        // Form case
        if (body instanceof Map) {
          Map<?, ?> bodyMap = (Map<?,?>) body;
          entityEnclosingRequest.setEntity(new UrlEncodedFormEntity(mapToNameValueList(bodyMap), HTTP.UTF_8));
          // Already an entity case
        } else if (body instanceof HttpEntity) {
          HttpEntity entity = (HttpEntity) body;
          entityEnclosingRequest.setEntity(entity);
        // Fall-back: string case
        } else {
          entityEnclosingRequest.setEntity(new StringEntity(body.toString(), HTTP.UTF_8));
        }
      }
    return request;
    }
    
    public static List<NameValuePair> mapToNameValueList(Map<?, ?> map) throws UnsupportedEncodingException {
    List<NameValuePair> nameValueList = new ArrayList<NameValuePair>(map.size());
    for(Map.Entry<?, ?> param : map.entrySet()) {
      NameValuePair nameValuePair = new BasicNameValuePair(param.getKey().toString(), param.getValue().toString());
      nameValueList.add(nameValuePair);
    }
    return nameValueList;
    }
    
  //-------------------------------------------------------------------------------------------
  // GZip compression
  
  private static void enableGzipCompression(DefaultHttpClient client) {
    // Gzip support
        client.addRequestInterceptor(new HttpRequestInterceptor() {
      @Override
      public void process(HttpRequest request, HttpContext context)
          throws HttpException, IOException {
                if (!request.containsHeader("Accept-Encoding")) {
                    request.addHeader("Accept-Encoding", "gzip");
                }
      }
    });

        client.addResponseInterceptor(new HttpResponseInterceptor() {
      @Override
      public void process(HttpResponse response, HttpContext context)
          throws HttpException, IOException {
                HttpEntity entity = response.getEntity();
                if(entity != null) {
                    Header ceheader = entity.getContentEncoding();
                    if (ceheader != null) {
                        HeaderElement[] codecs = ceheader.getElements();
                        for (int i = 0; i < codecs.length; i++) {
                            if (codecs[i].getName().equalsIgnoreCase("gzip")) {
                                response.setEntity(new GzipDecompressingEntity(response.getEntity()));
                                return;
                            }
                        }
                    }
                }
      }
    });
  }
  
  /**
   * GzipDecompressingEntity 
   */
  private static class GzipDecompressingEntity extends HttpEntityWrapper {

        public GzipDecompressingEntity(final HttpEntity entity) {
            super(entity);
        }

        @Override
        public InputStream getContent()
            throws IOException, IllegalStateException {

            // the wrapped entity's getContent() decides about repeatability
            InputStream wrappedin = wrappedEntity.getContent();
            return new GZIPInputStream(wrappedin);
        }

        @Override
        public long getContentLength() {
            // length of ungzipped content is not known
            return -1;
        }
  }
  
}




Java Source Code List

com.lightbox.android.bitmap.BitmapFileCleanerTask.java
com.lightbox.android.bitmap.BitmapLoaderListener.java
com.lightbox.android.bitmap.BitmapLoaderTask.java
com.lightbox.android.bitmap.BitmapLoader.java
com.lightbox.android.bitmap.BitmapSize.java
com.lightbox.android.bitmap.BitmapSource.java
com.lightbox.android.bitmap.BitmapUtils.java
com.lightbox.android.cache.AbstractCache.java
com.lightbox.android.cache.ApiCache.java
com.lightbox.android.cache.BitmapCache.java
com.lightbox.android.cache.Cache.java
com.lightbox.android.data.ClearAndSaveBatchTask.java
com.lightbox.android.data.Data.java
com.lightbox.android.data.DatabaseCleanerTask.java
com.lightbox.android.data.DatabaseHelper.java
com.lightbox.android.data.DeleteBatchTask.java
com.lightbox.android.data.SaveBatchTask.java
com.lightbox.android.io.RandomAccessFileOutputStream.java
com.lightbox.android.lifecycle.LifeCycleListener.java
com.lightbox.android.lifecycle.ManagedLifeCycleActivity.java
com.lightbox.android.location.LocationHelper.java
com.lightbox.android.location.LocationListener.java
com.lightbox.android.network.HttpHelper.java
com.lightbox.android.network.NetworkUtils.java
com.lightbox.android.operations.AbstractOperation.java
com.lightbox.android.operations.CachedOperation.java
com.lightbox.android.operations.DeleteOperation.java
com.lightbox.android.operations.FailureOperation.java
com.lightbox.android.operations.ModificationNetworkOnlyOperation.java
com.lightbox.android.operations.NetworkOnlyOperation.java
com.lightbox.android.operations.OperationListener.java
com.lightbox.android.operations.OperationTask.java
com.lightbox.android.operations.Operation.java
com.lightbox.android.operations.Retrievable.java
com.lightbox.android.operations.RetrieveOperation.java
com.lightbox.android.operations.SaveOperation.java
com.lightbox.android.operations.Updatable.java
com.lightbox.android.tasks.BackgroundTaskWeak.java
com.lightbox.android.tasks.BackgroundTask.java
com.lightbox.android.tasks.DefaultExecutor.java
com.lightbox.android.utils.AndroidUtils.java
com.lightbox.android.utils.Base64.java
com.lightbox.android.utils.IntentUtils.java
com.lightbox.android.utils.MediaUtils.java
com.lightbox.android.utils.ResUtils.java
com.lightbox.android.utils.debug.DebugLifeCycleListener.java
com.lightbox.android.utils.debug.DebugLog.java
com.lightbox.android.views.RemoteImageView.java
com.lightbox.android.views.RemoteThumbImageView.java
com.lightbox.android.webservices.processors.GenerationException.java
com.lightbox.android.webservices.processors.JacksonProcessor.java
com.lightbox.android.webservices.processors.ParsingException.java
com.lightbox.android.webservices.processors.Processor.java
com.lightbox.android.webservices.requests.ApiRequestFactory.java
com.lightbox.android.webservices.requests.ApiRequestListener.java
com.lightbox.android.webservices.requests.ApiRequestTask.java
com.lightbox.android.webservices.requests.ApiRequest.java
com.lightbox.android.webservices.requests.ApiRequests.java
com.lightbox.android.webservices.requests.JacksonApiRequestFactory.java
com.lightbox.android.webservices.responses.ApiException.java
com.lightbox.android.webservices.responses.ApiResponse.java
com.lightbox.tweetsnearby.TweetsNearbyApplication.java
com.lightbox.tweetsnearby.activities.MainActivity.java
com.lightbox.tweetsnearby.activities.PickPlaceActivity.java
com.lightbox.tweetsnearby.model.Tweet.java
com.lightbox.tweetsnearby.model.Venue.java
com.lightbox.tweetsnearby.responses.foursquare.FoursquareApiResponse.java
com.lightbox.tweetsnearby.responses.foursquare.VenueListResponse.java
com.lightbox.tweetsnearby.responses.twitter.TweetListResponse.java
com.lightbox.tweetsnearby.responses.twitter.TwitterApiResponse.java