package com.kendelong.util.http; import java.io.IOException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; 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.client.methods.HttpUriRequest; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Required; public class HttpConnectionService implements IHttpConnectionService { private final Log logger = LogFactory.getLog(this.getClass()); public static final String ENCODING = "UTF-8"; private IHttpClientStrategy httpClientStrategy; @Override public HttpResponseObject postStringAsRequestEntity(String connectionURL, String data, String contentType, Map<String, String> headers) throws Exception { HttpPost postRequest = new HttpPost(connectionURL); StringEntity entity = new StringEntity(data, ENCODING); entity.setContentType(contentType); postRequest.setEntity(entity); for(String name : headers.keySet()) { postRequest.setHeader(name, headers.get(name)); } return doExecuteAndGetResponse(postRequest); } @Override public HttpResponseObject postStringAsRequestEntity(String connectionURL, String data, String contentType) throws Exception { Map<String, String> headers = new HashMap<>(); return postStringAsRequestEntity(connectionURL, data, contentType, headers); } @Override public HttpResponseObject postStringAsXml(String connectionURL, String data) throws Exception { return postStringAsRequestEntity(connectionURL, data, "text/xml"); } @Override public HttpResponseObject postStringAsJson(String connectionURL, String data) throws Exception { return postStringAsRequestEntity(connectionURL, data, "application/json"); } @Override public HttpResponseObject postData(String connectionURL, Map<String, String> parameters) throws Exception { HttpPost postRequest = new HttpPost(connectionURL); // Put the parameters in the request List<NameValuePair> nvPairs = new ArrayList<NameValuePair>(); for(Map.Entry<String, String> entry : parameters.entrySet()) { NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue()); nvPairs.add(pair); } UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvPairs, ENCODING); postRequest.setEntity(entity); return doExecuteAndGetResponse(postRequest); } @Override public HttpResponseObject getResult(String connectionUrl, Map<String, String> parameters, Map<String, String> headers) throws Exception { // add parameters to GET StringBuilder urlWithParams = new StringBuilder(connectionUrl); if(parameters != null && !parameters.isEmpty()) { urlWithParams.append("?"); for(String key : parameters.keySet()) { String value = URLEncoder.encode(parameters.get(key), ENCODING); urlWithParams.append(key).append("=").append(value).append("&"); } urlWithParams.deleteCharAt(urlWithParams.length() - 1); // Wish I had Groovy here...sigh. } HttpGet getRequest = new HttpGet(urlWithParams.toString()); for(String name : headers.keySet()) { getRequest.setHeader(name, headers.get(name)); } return doExecuteAndGetResponse(getRequest); } @Override public HttpResponseObject getResult(String connectionUrl, Map<String, String> parameters) throws Exception { Map<String, String> headers = new HashMap<>(); return getResult(connectionUrl, parameters, headers); } @Override public HttpResponseObject simpleGet(String url) throws Exception { HttpGet getRequest = new HttpGet(url); return doExecuteAndGetResponse(getRequest); } /** * Execute the method and pass it to be processed and populate an * HttpResponseObject with the response data. * * @param httpRequest Method to be executed * @return response object populated with body, headers, length, status info * @throws IOException */ private HttpResponseObject doExecuteAndGetResponse(HttpUriRequest httpRequest) throws IOException { HttpClient client = getHttpClientStrategy().getHttpClient(); HttpResponseObject response = null; try { logger.debug("Executing [" + httpRequest.getRequestLine() + "]"); // Send the data and get the response HttpResponseHandler handler = new HttpResponseHandler(); response = client.execute(httpRequest, handler); } catch(ClientProtocolException e) { logger.warn("Fatal protocol violation: " + e.getMessage()); throw e; } catch(IOException e) { logger.warn("Fatal transport error: " + e.getMessage()); throw e; } return response; } private class HttpResponseHandler implements ResponseHandler<HttpResponseObject> { @Override public HttpResponseObject handleResponse(HttpResponse response) throws ClientProtocolException, IOException { HttpResponseObject responseObject = new HttpResponseObject(); HttpEntity entity = response.getEntity(); String body = EntityUtils.toString(entity, ENCODING); long length = (entity != null ? entity.getContentLength() : 0); Header contentType = (entity != null ? entity.getContentType() : null); String encoding = (contentType != null ? contentType.getValue() : ENCODING); responseObject.setBody(body); responseObject.setHeaders(response.getAllHeaders()); responseObject.setLength(length); responseObject.setStatusCode(response.getStatusLine().getStatusCode()); responseObject.setStatusText(response.getStatusLine().getReasonPhrase()); if(logger.isDebugEnabled()) { logger.debug("Received reponse from remote server." + " Use logger httpclient.wire.content=DEBUG to see it." + " Response was [" + responseObject.getLength() + "] characters long; encoding was [" + encoding +"]"); logger.trace(responseObject.getBody()); } return responseObject; } } public IHttpClientStrategy getHttpClientStrategy() { return httpClientStrategy; } @Required public void setHttpClientStrategy(IHttpClientStrategy httpClientStrategy) { this.httpClientStrategy = httpClientStrategy; } }