com.itude.mobile.mobbl.server.http.HttpDelegate.java Source code

Java tutorial

Introduction

Here is the source code for com.itude.mobile.mobbl.server.http.HttpDelegate.java

Source

/*
 * (C) Copyright Itude Mobile B.V., The Netherlands
 * 
 * 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.itude.mobile.mobbl.server.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.TreeMap;

import javax.servlet.http.Cookie;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.log4j.Logger;

import com.itude.mobile.mobbl.server.mobileweb.Constants;
import com.itude.mobile.mobbl.server.util.HeaderUtil;

public class HttpDelegate {
    // http://hc.apache.org/httpclient-3.x/threading.html#MultiThreadedHttpConnectionManager
    private static final int TOTAL_CONNECTIONS = 50;
    private static final int CONNECTIONS_PER_HOST = 20;
    private static final int CONNECTION_TIMEOUT = 30 * 1000;

    private HttpClient httpClient = null;

    private static HttpDelegate _instance = null;
    private static final Logger logger = Logger.getLogger(HttpDelegate.class.getName());

    public static HttpDelegate getInstance() {
        if (_instance == null)
            _instance = new HttpDelegate();
        return _instance;
    }

    private HttpDelegate() {
        logger.debug("HttpDelegate.HttpDelegate()");

        MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
        HttpConnectionManagerParams connectionParameters = connectionManager.getParams();
        connectionParameters.setDefaultMaxConnectionsPerHost(CONNECTIONS_PER_HOST);
        connectionParameters.setMaxTotalConnections(TOTAL_CONNECTIONS);
        connectionParameters.setConnectionTimeout(CONNECTION_TIMEOUT);

        httpClient = new HttpClient(connectionManager);
    }

    public HttpResponse connectGet(String url) {
        return connectGet(url, new Header[0]);
    }

    public HttpResponse connectGet(String url, TreeMap<String, String[]> requestHeaders) {
        Header[] headers = transformToHeader(requestHeaders);
        return connectGet(url, headers);
    }

    public HttpResponse connectGet(String url, Header[] requestHeaders) {
        return connectGet(url, null, null, requestHeaders, false);
    }

    public HttpResponse connectGet(String url, String userAgent, ArrayList<Cookie> reqCookies,
            Header[] requestHeaders, boolean followRedirects) {
        logger.debug("HttpDelegate.connectGet(): " + url);

        GetMethod get = new GetMethod(url);
        try {
            prepareConnection(get, userAgent, reqCookies, requestHeaders, !url.contains("acceptxml=false"),
                    followRedirects);
            if (logger.isDebugEnabled())
                HeaderUtil.printRequestHeaders(logger, get);

            return executeHttpMethod(get);
        } catch (HttpException e) {
            logger.error(e.getMessage());
            logger.trace(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage());
            logger.trace(e.getMessage(), e);
        } finally {
            get.releaseConnection();
        }

        return null;
    }

    public HttpResponse connectPost(String url, NameValuePair[] postData) {
        return connectPost(url, postData, new Header[0]);
    }

    public HttpResponse connectPost(String url, NameValuePair[] postData,
            TreeMap<String, String[]> requestHeaders) {
        Header[] headers = transformToHeader(requestHeaders);
        return connectPost(url, postData, headers);
    }

    public HttpResponse connectPost(String url, NameValuePair[] postData, Header[] requestHeaders) {
        return connectPost(url, null, null, postData, requestHeaders, false);
    }

    public HttpResponse connectPost(String url, String userAgent, ArrayList<Cookie> reqCookies,
            NameValuePair[] postData, Header[] requestHeaders, boolean followRedirects) {
        logger.debug("HttpDelegate.connectPost(): " + url);

        PostMethod post = new PostMethod(url);
        try {
            prepareConnection(post, userAgent, reqCookies, requestHeaders, !url.contains("acceptxml=false"),
                    followRedirects);
            if (postData != null)
                post.setRequestBody(postData);

            return executeHttpMethod(post);
        } catch (HttpException e) {
            logger.error(e.getMessage());
            logger.trace(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage());
            logger.trace(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }

        return null;
    }

    private HttpResponse executeHttpMethod(HttpMethod method) throws HttpException, IOException {
        HttpResponse response = new HttpResponse();
        String responseHeader = null;

        response.setResponseCode(httpClient.executeMethod(method));
        try {
            responseHeader = method.getResponseHeader(Constants.CONTENT_TYPE).getValue();
        } catch (NullPointerException e) {
            logger.debug("ResponseHeader was null");
        }

        if (responseHeader != null)
            response.setContentType(responseHeader);
        //    response.setResponseBody(method.getResponseBody());
        response.setResponseHeaders(method.getResponseHeaders());
        response.setResponseStatusLine(response.getResponseStatusLine());
        Header contentLength = method.getResponseHeader(Constants.CONTENT_LENGTH);
        if (contentLength != null)
            response.setContentLength(contentLength.getValue());

        if (response.getContentLength() > -1) {
            InputStream stream = null;
            byte[] body = new byte[response.getContentLength()];
            try {
                stream = method.getResponseBodyAsStream();

                int offset = 0;
                int i = -1;
                while ((i = stream.read(body, offset, 1024)) != -1)
                    offset += i;
                response.setResponseBody(body);
            } catch (Exception e) {
                logger.error("Could not read entire response body", e);
            } finally {
                if (stream != null)
                    stream.close();
            }
        } else {
            logger.debug("Content-length unknown");

            InputStream stream = null;
            ByteArrayOutputStream body = new ByteArrayOutputStream();
            try {
                stream = method.getResponseBodyAsStream();

                int i = -1;
                while ((i = stream.read()) != -1)
                    body.write(i);

                response.setResponseBody(body.toByteArray());
                response.setContentLength(body.size());
            } catch (Exception e) {
                logger.error("Could not read entire response body", e);
            } finally {
                body.close();
                if (stream != null)
                    stream.close();
            }
        }

        return response;
    }

    private void prepareConnection(HttpMethod method, String userAgent, ArrayList<Cookie> cookies,
            Header[] requestHeaders, boolean acceptXml, boolean followRedirects) {
        logger.debug("HttpDelegate.prepareConnection()");

        if (logger.isDebugEnabled())
            HeaderUtil.printRequestHeaders(logger, method);

        if (acceptXml)
            method.addRequestHeader("Accept", "application/xml, */*");

        if (cookies != null) {
            for (Cookie cookie : cookies)
                method.addRequestHeader("Cookie", cookie.getName() + "=" + cookie.getValue());
        }

        if (userAgent != null)
            method.addRequestHeader(Constants.USER_AGENT, userAgent);

        method.setFollowRedirects(followRedirects);

        if (requestHeaders != null)
            for (Header h : requestHeaders)
                method.addRequestHeader(h);

    }

    private synchronized Header[] transformToHeader(TreeMap<String, String[]> headers) {
        if (headers == null)
            return null;

        Header[] result = new Header[headers.size()];
        Iterator<Entry<String, String[]>> iterator = headers.entrySet().iterator();

        int i = 0;
        while (iterator.hasNext()) {
            Entry<String, String[]> entry = iterator.next();
            for (String s : entry.getValue())
                result[i] = new Header(entry.getKey(), s);
            i++;
        }

        return result;
    }
}