HttpComponent3.java
package com.foxinmy.weixin4j.http.support.apache3;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map.Entry;
import javax.net.ssl.SSLContext;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.OptionsMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.TraceMethod;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import com.foxinmy.weixin4j.http.AbstractHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.apache.mime.MultipartEntity;
import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.util.Consts;
import com.foxinmy.weixin4j.util.StringUtil;
/**
* Requires commons-httpclient 3.0 or higher
*
* @className HttpComponent3
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月18日
* @since JDK 1.6
* @see
*/
public class HttpComponent3 extends AbstractHttpClient {
private final org.apache.commons.httpclient.HttpClient httpClient;
public HttpComponent3(org.apache.commons.httpclient.HttpClient httpClient) {
this.httpClient = httpClient;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
org.apache.commons.httpclient.HttpMethod httpMethod = createRequest(request);
httpClient.executeMethod(httpMethod);
response = new HttpComponent3Response(httpMethod);
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
/**
* Create HttpRequest
*/
protected org.apache.commons.httpclient.HttpMethod createRequest(
HttpRequest request) throws HttpClientException, IOException {
org.apache.commons.httpclient.HttpMethod httpMethod = createMethod(request);
resolveHeaders(request, httpMethod);
resolveContent(request, httpMethod);
return httpMethod;
}
/**
* Create HttpMethod
*/
protected org.apache.commons.httpclient.HttpMethod createMethod(
HttpRequest request) throws HttpClientException {
HttpMethod method = request.getMethod();
org.apache.commons.httpclient.HttpMethod httpMethod = null;
try {
URI uri = new URI(request.getURI().toString(), false,
Consts.UTF_8.name());
if (method == HttpMethod.GET) {
httpMethod = new GetMethod();
} else if (method == HttpMethod.HEAD) {
httpMethod = new HeadMethod();
} else if (method == HttpMethod.POST) {
httpMethod = new PostMethod();
} else if (method == HttpMethod.PUT) {
return new PutMethod();
} else if (method == HttpMethod.DELETE) {
httpMethod = new DeleteMethod();
} else if (method == HttpMethod.OPTIONS) {
httpMethod = new OptionsMethod();
} else if (method == HttpMethod.TRACE) {
return new TraceMethod(uri.getEscapedURI());
} else {
throw new HttpClientException("unknown request method "
+ method + " for " + uri);
}
httpMethod.setURI(uri);
} catch (IOException e) {
throw new HttpClientException("I/O error on " + method.name()
+ " setURI for \"" + request.toString() + "\":"
+ e.getMessage(), e);
}
return httpMethod;
}
/**
* Resolve Headers
*/
protected void resolveHeaders(HttpRequest request,
org.apache.commons.httpclient.HttpMethod httpMethod) {
com.foxinmy.weixin4j.http.HttpHeaders headers = request.getHeaders();
if (headers == null) {
headers = new HttpHeaders();
}
if (!headers.containsKey(HttpHeaders.HOST)) {
headers.set(HttpHeaders.HOST, request.getURI().getHost());
}
// Add default accept headers
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
headers.set(HttpHeaders.ACCEPT, "*/*");
}
// Add default user agent
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "apache/httpclient3");
}
for (Entry<String, List<String>> header : headers.entrySet()) {
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
httpMethod.setRequestHeader(header.getKey(),
StringUtil.join(header.getValue(), ';'));
} else {
for (String headerValue : header.getValue()) {
httpMethod.setRequestHeader(header.getKey(),
headerValue != null ? headerValue : "");
}
}
}
}
/**
* Resolve Content
*/
protected void resolveContent(HttpRequest request,
org.apache.commons.httpclient.HttpMethod httpMethod)
throws IOException {
HttpEntity entity = request.getEntity();
if (entity != null) {
if (entity.getContentLength() > 0l) {
httpMethod.addRequestHeader(HttpHeaders.CONTENT_LENGTH,
Long.toString(entity.getContentLength()));
}
if (entity.getContentType() != null) {
httpMethod.addRequestHeader(HttpHeaders.CONTENT_TYPE, entity
.getContentType().toString());
}
RequestEntity requestEntity = null;
if (entity instanceof MultipartEntity) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
entity.writeTo(os);
os.flush();
requestEntity = new ByteArrayRequestEntity(os.toByteArray(),
entity.getContentType().toString());
os.close();
} else {
requestEntity = new InputStreamRequestEntity(
entity.getContent(), entity.getContentType().toString());
}
((EntityEnclosingMethod) httpMethod)
.setRequestEntity(requestEntity);
}
}
public static class SSLProtocolSocketFactory implements
SecureProtocolSocketFactory {
private final SSLContext sslContext;
public SSLProtocolSocketFactory(SSLContext sslContext) {
this.sslContext = sslContext;
}
@Override
public Socket createSocket(String host, int port,
InetAddress localAddress, int localPort) throws IOException,
UnknownHostException {
return sslContext.getSocketFactory().createSocket(host, port,
localAddress, localPort);
}
@Override
public Socket createSocket(String host, int port,
InetAddress localAddress, int localPort,
HttpConnectionParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
if (timeout == 0) {
return createSocket(host, port, localAddress, localPort);
} else {
return ControllerThreadSocketFactory.createSocket(this, host,
port, localAddress, localPort, timeout);
}
}
@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
return sslContext.getSocketFactory().createSocket(host, port);
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host,
port, autoClose);
}
}
}