package com.qcloud.cos.http; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.util.Map; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpMessage; import org.apache.http.HttpResponse; import org.apache.http.ParseException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.util.EntityUtils; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.exception.AbstractCosException; import com.qcloud.cos.exception.ParamException; import com.qcloud.cos.exception.ServerException; import com.qcloud.cos.exception.UnknownException; import com.qcloud.cos.meta.COSObjectInputStream; /** * @author chengwu 封装Http发送请求类 */ public class DefaultCosHttpClient extends AbstractCosHttpClient { private static final Logger LOG = LoggerFactory.getLogger(DefaultCosHttpClient.class); public DefaultCosHttpClient(ClientConfig config) { super(config); } // 获得异常发生时的返回信息 private String getExceptionMsg(HttpRequest httpRequest, String exceptionStr) { String errMsg = new StringBuilder("HttpRequest:").append(httpRequest.toString()) .append("\nException:").append(exceptionStr).toString(); LOG.error(errMsg); return errMsg; } /** * Get请求函数 * * @param url * @param headers 额外添加的Http头部 * @param params GET请求的参数 * @return Cos服务器返回的字符串 * @throws Exception */ @Override protected String sendGetRequest(HttpRequest httpRequest) throws AbstractCosException { String url = httpRequest.getUrl(); HttpGet httpGet = null; String responseStr = ""; int retry = 0; int maxRetryCount = this.config.getMaxFailedRetry(); while (retry < maxRetryCount) { try { URIBuilder urlBuilder = new URIBuilder(url); for (String paramKey : httpRequest.getParams().keySet()) { urlBuilder.addParameter(paramKey, httpRequest.getParams().get(paramKey)); } httpGet = new HttpGet(urlBuilder.build()); } catch (URISyntaxException e) { String errMsg = "Invalid url:" + url; LOG.error(errMsg); throw new ParamException(errMsg); } httpGet.setConfig(requestConfig); setHeaders(httpGet, httpRequest.getHeaders()); HttpResponse httpResponse = null; try { httpResponse = httpClient.execute(httpGet); int http_statuscode = httpResponse.getStatusLine().getStatusCode(); if (http_statuscode >= 500 && http_statuscode <= 599) { String errMsg = String.format("http status code is %d, response body: %s", http_statuscode, getResponseString(httpResponse)); throw new IOException(errMsg); } responseStr = getResponseString(httpResponse); new JSONObject(responseStr); httpGet.releaseConnection(); return responseStr; } catch (ParseException e) { httpGet.abort(); ++retry; if (retry == maxRetryCount) { String errMsg = getExceptionMsg(httpRequest, e.toString()); throw new ServerException(errMsg); } } catch (IOException e) { httpGet.abort(); ++retry; if (retry == maxRetryCount) { String errMsg = getExceptionMsg(httpRequest, e.toString()); throw new ServerException(errMsg); } } catch (JSONException e) { httpGet.abort(); String errMsg = String.format( "server response is not json, httpRequest: %s, httpResponse: %s, responseStr: %s", httpRequest.toString(), httpResponse.toString(), responseStr); throw new ServerException(errMsg); } } return responseStr; } @Override protected String sendPostRequest(HttpRequest httpRequest) throws AbstractCosException { String url = httpRequest.getUrl(); String responseStr = ""; int retry = 0; int maxRetryCount = this.config.getMaxFailedRetry(); while (retry < maxRetryCount) { HttpPost httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); Map<String, String> params = httpRequest.getParams(); setHeaders(httpPost, httpRequest.getHeaders()); if (httpRequest.getContentType() == HttpContentType.APPLICATION_JSON) { setJsonEntity(httpPost, params); } else if (httpRequest.getContentType() == HttpContentType.MULTIPART_FORM_DATA) { try { setMultiPartEntity(httpPost, params); } catch (Exception e) { throw new UnknownException(e.toString()); } } HttpResponse httpResponse = null; try { httpResponse = httpClient.execute(httpPost); int http_statuscode = httpResponse.getStatusLine().getStatusCode(); if (http_statuscode >= 500 && http_statuscode <= 599) { String errMsg = String.format("http status code is %d, response body: %s", http_statuscode, getResponseString(httpResponse)); throw new IOException(errMsg); } responseStr = getResponseString(httpResponse); new JSONObject(responseStr); httpPost.releaseConnection(); return responseStr; } catch (ParseException e) { httpPost.abort(); ++retry; if (retry == maxRetryCount) { String errMsg = getExceptionMsg(httpRequest, e.toString()); throw new ServerException(errMsg); } } catch (IOException e) { httpPost.abort(); ++retry; if (retry == maxRetryCount) { String errMsg = getExceptionMsg(httpRequest, e.toString()); throw new ServerException(errMsg); } } catch (JSONException e) { httpPost.abort(); String errMsg = String.format( "server response is not json, httpRequest: %s, httpResponse: %s, responseStr: %s", httpRequest.toString(), httpResponse.toString(), responseStr); throw new ServerException(errMsg); } } return responseStr; } @Override public InputStream getFileInputStream(HttpRequest httpRequest) throws AbstractCosException { String url = httpRequest.getUrl(); int retry = 0; int maxRetryCount = this.config.getMaxFailedRetry(); while (retry < maxRetryCount) { HttpGet httpGet = null; try { URIBuilder urlBuilder = new URIBuilder(url); for (String paramKey : httpRequest.getParams().keySet()) { urlBuilder.addParameter(paramKey, httpRequest.getParams().get(paramKey)); } httpGet = new HttpGet(urlBuilder.build()); } catch (URISyntaxException e) { String errMsg = "Invalid url:" + url; LOG.error(errMsg); throw new ParamException(errMsg); } httpGet.setConfig(requestConfig); setHeaders(httpGet, httpRequest.getHeaders()); try { HttpResponse httpResponse = httpClient.execute(httpGet); int http_statuscode = httpResponse.getStatusLine().getStatusCode(); if (http_statuscode >= 500 && http_statuscode <= 599) { String errMsg = String.format("http status code is %d, response body: %s", http_statuscode, getResponseString(httpResponse)); throw new IOException(errMsg); } if (http_statuscode != 200 && http_statuscode != 206) { String responseStr = getResponseString(httpResponse); String errMsg = String.format( "getFileinputstream failed, httpRequest: %s, httpResponse: %s, responseStr: %s", httpRequest.toString(), httpResponse.toString(), responseStr); httpGet.releaseConnection(); throw new ServerException(errMsg); } HttpEntity entity = httpResponse.getEntity(); COSObjectInputStream cosObjectInputStream = new COSObjectInputStream(entity.getContent(), httpGet); return cosObjectInputStream; } catch (ParseException e) { ++retry; httpGet.abort(); if (retry == maxRetryCount) { String errMsg = getExceptionMsg(httpRequest, e.toString()); throw new ServerException(errMsg); } } catch (IOException e) { ++retry; httpGet.abort(); if (retry == maxRetryCount) { String errMsg = getExceptionMsg(httpRequest, e.toString()); throw new ServerException(errMsg); } } } // never will reach here return null; } private String getResponseString(HttpResponse httpResponse) throws ParseException, IOException { String httpResponseStr = null; HttpEntity httpEntity = httpResponse.getEntity(); if (httpEntity != null) { httpResponseStr = EntityUtils.toString(httpEntity, "UTF-8"); } if (httpResponseStr == null) { return ""; } else { return httpResponseStr; } } private void setJsonEntity(HttpPost httpPost, Map<String, String> params) { ContentType utf8TextPlain = ContentType.create("text/plain", Consts.UTF_8); String postJsonStr = new JSONObject(params).toString(); StringEntity stringEntity = new StringEntity(postJsonStr, utf8TextPlain); httpPost.setEntity(stringEntity); } private void setMultiPartEntity(HttpPost httpPost, Map<String, String> params) throws Exception { ContentType utf8TextPlain = ContentType.create("text/plain", Consts.UTF_8); MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); for (String paramKey : params.keySet()) { if (paramKey.equals(RequestBodyKey.FILE_CONTENT)) { entityBuilder.addBinaryBody(RequestBodyKey.FILE_CONTENT, params .get(RequestBodyKey.FILE_CONTENT).getBytes(Charset.forName("ISO-8859-1"))); } else { entityBuilder.addTextBody(paramKey, params.get(paramKey), utf8TextPlain); } } httpPost.setEntity(entityBuilder.build()); } /** * 设置Http头部,同时添加上公共的类型,长连接,COS SDK标识 * * @param message HTTP消息 * @param headers 用户额外添加的HTTP头部 */ private void setHeaders(HttpMessage message, Map<String, String> headers) { message.setHeader(RequestHeaderKey.ACCEPT, RequestHeaderValue.Accept.ALL); message.setHeader(RequestHeaderKey.CONNECTION, RequestHeaderValue.Connection.KEEP_ALIVE); message.setHeader(RequestHeaderKey.USER_AGENT, this.config.getUserAgent()); if (headers != null) { for (String headerKey : headers.keySet()) { message.setHeader(headerKey, headers.get(headerKey)); } } } }