封装使用HttpClient客户端

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
HttpClient提供非常方便而全面的API提供Http协议编程访问网络资源。
我的习惯是当我使用任何一个第三方工具或者一些开源框架编程的时候,我都会适当的做一些封装以尽量符合我的需求和使用。
当然,直接使用其API也能完成自己的功能,但是这些工具或者框架一般都是大而全的,在使用的时候我们常常只需要其中的一小部分功能,或者需要扩展其某一方面的功能。这样我们如果能按照自己的需求适当封装的话,能尽量减少我们客户端使用时的简单和纯粹。

一、定义Http请求返回数据处理接口HttpClientResponseHandler:
/**
 * HttpClient请求web服务器响应数据处理接口
 * @author boyce
 * @version 2014-1-24
 */
public interface HttpClientResponseHandler {
    
    public void handle(String response) throws HttpClientException ;
}


二、定义HttpClient请求接口HttpClientRequest:

/**
 * HttpClient 请求web服务器的request
 * @author boyce
 * @version 2014-1-24
 */
public interface HttpClientRequest {
    /**
     * 添加request参数
     * @param name 参数名
     * @param value 参数值
     */
    public void addParam(String name, Object value);
    
    /**
     * 执行request请求
     * @param httpClientResponseHandler 处理响应数据handler
     * @throws HttpClientException
     */
    public void process(HttpClientResponseHandler httpClientResponseHandler) throws HttpClientException ;
    
}

三、实现一个抽象的HttpClientRequest,封装post和get请求的公共部分:

/**
 * 抽象HttpClient 请求web服务器的request
 * @author boyce
 * @version 2014-1-24
 */
public abstract class AbstractHttpClientRequest implements HttpClientRequest {
    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AbstractHttpClientRequest.class);
    
    //请求URL地址
    protected String url;
    //请求参数
    protected Map<String, Object> params;
    
    /**
     * Constructor Method With All Params
     * @param url 请求URL
     */
    public AbstractHttpClientRequest(String url) {
        if (StringUtils.isEmpty(url))
            throw new NullPointerException("Cannot constract a HttpClientRequest with empty url.");
        
        this.url = url;
        this.params = new HashMap<String, Object>();
    }

    /**
     * 添加request参数
     * @param name 参数名
     * @param value 参数值
     */
    public void addParam(String name, Object value) {
        this.params.put(name, value);
    }
    
    /**
     * 执行请求
     * @throws HttpClientException httpClient请求异常
     */
    public void process(HttpClientResponseHandler httpClientResponseHandler) throws HttpClientException {
        
        //获取子类的具体的HttpMethod实现
        HttpMethod httpMethod = this.getHttpMethod();
        
        if (ObjectUtils.isNull(httpMethod))
            throw new NullPointerException("Cannot process request because the httpMethod is null.");
        
        HttpClient httpClient = new HttpClient();
        httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
        
        try {
            long start = System.currentTimeMillis();
            logger.info("Begin to visit {}.", httpMethod.getURI());
            
            httpClient.executeMethod(httpMethod);
            logger.info("End to visit and take: {} ms.", (System.currentTimeMillis() - start));
        } catch (IOException e) {
            throw new HttpClientException(httpMethod.getPath(), e.getMessage());
        }
        
        //利用HttpClientResponseHandler处理响应结果
        if (ObjectUtils.isNotNull(httpClientResponseHandler))
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(httpMethod.getResponseBodyAsStream()));  
                StringBuilder builder = new StringBuilder();  
                String str = null;  
                while((str = reader.readLine()) != null){  
                    builder.append(str);  
                }  
                String response = builder.toString(); 
                httpClientResponseHandler.handle(response);
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
            
        httpMethod.releaseConnection();
    }

    /**
     * 子类实现返回具体的HttpMethod对象
     * @return HttpMethod
     */
    public abstract HttpMethod getHttpMethod();
    
}


四、实现一个HttpClientGetRequest:
/**
 * 通过HttpClient GET请求服务器数据的Request
 * @author boyce
 * @version 2014-1-23
 */
public class HttpClientGetRequest extends AbstractHttpClientRequest {
    
    public HttpClientGetRequest(String url) {
        super(url);
    }
    
    public HttpMethod getHttpMethod() {
        StringBuilder builder = new StringBuilder();
        for (Entry<String, Object> entry : params.entrySet()) {
                builder.append(entry.getKey()).append("=")
                        .append(String.valueOf(entry.getValue()))
                        .append("&");
        }
        String param = null;
        if (builder.length() != 0)
            param = builder.deleteCharAt(builder.length()-1).toString();
        
        String url = null;
        if (StringUtils.isEmpty(param))
            url = this.url;
        else
            url = this.url + "?" + param;
        
        HttpMethod httpMethod = new GetMethod(url);
        return httpMethod;
    }
    
}


五、实现一个HttpClientPostRequest:
    /**
 * 通过HttpClient Post请求服务器数据的Request
 * @author boyce
 * @version 2014-1-23
 */
public class HttpClientPostRequest extends AbstractHttpClientRequest {

    public HttpClientPostRequest(String url) {
        super(url);
    }

    public HttpMethod getHttpMethod() {
        NameValuePair[] pairs = new NameValuePair[this.params.size()];
        NameValuePair pair = null;
        int i = 0;
        for (Entry<String, Object> entry : params.entrySet()) {
            pair = new NameValuePair(entry.getKey(), String.valueOf(entry.getValue()));
            pairs[i++] = pair;
        }
        
        PostMethod httpMethod = new PostMethod(this.url);
        httpMethod.setRequestBody(pairs);
        
        if (StringUtils.isNotEmpty(contentType))
            httpMethod.setRequestHeader("Content-Type", contentType);
        
        return httpMethod;
    }

}


六、客户端使用:
HttpClientRequest request = new HttpClientGetRequest("http://www.baidu.com");
request.process(new HttpClientResponseHandler() {
    /**
     * 处理response的数据
     */
    public void handle(String response) throws HttpClientException {
        System.out.println(response);
    }
});


有需要的同学参考,当然你可以按照自己的业务对HttpClientResponseHandler接口做更丰富的封装,
包括HttpClientRequest接口也可以更加丰富。
各位同学有什么改进意见和建议欢迎留言,共同学习,感激不尽!


你可能感兴趣的:(httpclient,封装)