自己写的简单HttpClient

前几天写了个多线程通过HTTP下载文件的小程序,其中简单写了个HttpClient. 源码:GitHub

1 定义一个抽象BaseHttpMethod类

public abstract class BaseHttpMethod {
    protected static String HEAD = "HEAD";
    protected static String GET = "GET";
    protected static String POST = "POST";
    String url;
    protected  Map paras = new HashMap();

    protected abstract String getMethod();
    protected abstract BaseBuilder getBuilder();
    protected Map getParamters(){
        return paras;
    }
    public void putParamter(String key,Object value){
        paras.put(key, value);
    }
    protected void setUrl(String url) {
        this.url = url;
    }
    protected String getUrl(){
        return url;
    }

    protected BaseHttpMethod() {

    }

    protected BaseHttpMethod(String url) {
        this.url = url;
    }
}

下面定义了3个实现类:HttpGet,HttpPost,HttpHead

public class HttpPost extends BaseHttpMethod {

    @Override
    public String getMethod() {
        return POST;
    }

    public HttpPost() {
    }

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

    @Override
    protected BaseBuilder getBuilder() {
        return new PostConnectBuilder(this);
    }
}

其他2个HttpGet,HttpHead和这个差不多
#2 定义一个Response 接口IHttpResponse
public interface IHttpResponse {

    public int getStatusCode() throws IOException;
    public InputStream getInputStream() throws IOException;
    public String getContent();
    public Map<String, List<String>> getHeaders();
    public String getHeader(String name);
    public void close();
}

HttpResponse简单实现了这个接口
public class HttpResponse implements IHttpResponse {

    private InputStream inputStream;
    private HttpURLConnection con;

    public HttpResponse(HttpURLConnection con) {
        this.con = con;
    }

    @Override
    public int getStatusCode() throws IOException {

        return con != null ? con.getResponseCode() : -1;

    }

    @Override
    public InputStream getInputStream() throws IOException {

        inputStream = null != con ? con.getInputStream() : null;

        return inputStream;
    }

    @Override
    public String getContent() {
        if (inputStream != null) {
            StringBuffer content = new StringBuffer();
            BufferedInputStream bufferInputStream = new BufferedInputStream(
                    inputStream);
            byte[] data = new byte[1024];
            int length;
            try {
                while ((length = bufferInputStream.read(data)) > 0) {
                    content.append(new String(data, 0, length));
                }
                return content.toString();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public Map<String, List<String>> getHeaders() {
        return null != con ? con.getHeaderFields() : null;
    }

    @Override
    public String getHeader(String name) {
        return null != con ? con.getHeaderField(name) : null;
    }

    @Override
    public void close() {
        if (null != null)
            con.disconnect();
    }
}

3 简单定义一个HttpClient

public class HttpClient {
    public static String HEAD = "HEAD";
    public static String GET = "GET";
    public static String POST = "POST";
    private static HttpClient instance;
    private HttpClient (){

    }
    public static HttpClient getInstance(){
        if(null == instance){
            synchronized (HttpClient .class) {
                instance =new HttpClient ();
            }
        }
        return instance;
    }

    public IHttpResponse exec(BaseHttpMethod method) throws IOException{
        return exec(method,null);
    }
    public IHttpResponse exec(BaseHttpMethod method,Map property) throws IOException{
        HttpURLConnection con = ConnectFactory.getInstance().getCon(method,property);
        return new HttpResponse(con);
    }


}

这里用到一个ConnectFactory 来获得URLHttpConnection

4 一个简单ConnectFactory

public class ConnectFactory {
    private static int CON_TIME_OUT = 5 * 100;
    private static int READ_TIME_OUT = 10 * 1000;

    public void setConnectTimeout(int connectTimeout) {
        CON_TIME_OUT = connectTimeout;
    }

    public void setReadTimeout(int readTimeout) {
        READ_TIME_OUT = readTimeout;
    }

    private static ConnectFactory instance;

    private ConnectFactory() {

    }

    public static ConnectFactory getInstance() {
        if (null == instance) {
            synchronized (ConnectFactory.class) {
                instance = new ConnectFactory();
            }
        }
        return instance;
    }

    public HttpURLConnection getCon(BaseHttpMethod method,Map<String,String> property) throws IOException {

        HttpURLConnection con = method.getBuilder().build();

        con.setConnectTimeout(CON_TIME_OUT);
        con.setReadTimeout(READ_TIME_OUT);
        if(null != property && property.size()>0){
            Iterator keyIt = property.keySet().iterator();
            while(keyIt.hasNext()){
                String key = (String) keyIt.next();
                String value = property.get(key);
                con.setRequestProperty(key,value);
            }
        }
        //some sites will refuse, if no "User-Agent", so set default value
        if(property==null || !property.containsKey("User-Agent")){
            con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0");
        }

        con.connect();
        method.getBuilder().doOutPut(con);
        return con;
    }
    public HttpURLConnection getCon(BaseHttpMethod method) throws IOException {
        return getCon(method, null);
    }
}

在这个工厂方法中用到了一个Builder, 其中的抽象类为:
public abstract class BaseBuilder {

    protected BaseHttpMethod method;
    public BaseBuilder(BaseHttpMethod method) {
        this.method=method;
    }
    protected void doOutPut(HttpURLConnection con){

    }
    protected abstract HttpURLConnection build() throws IOException;
    protected String buildParamters(){
        Map paras = method.getParamters();
        StringBuffer sb = new StringBuffer();
        if(paras!=null && paras.size()>0){
            Iterator<String> keyIt = paras.keySet().iterator();
            while(keyIt.hasNext()){
                String key = keyIt.next();
                String value = (String) paras.get(key);
                String encodedValue = null;
                try {
                    encodedValue = URLEncoder.encode(value, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                if(encodedValue!=null){
                    sb.append(key).append("=").append(encodedValue);
                }else{
                    sb.append(key).append("=").append(value);
                }
                if(keyIt.hasNext())sb.append("&");
            }
        }
        return sb.toString();
    }
}

其中的HeadConnectBuilder
public class HeadConnectBuilder extends BaseBuilder {

    public HeadConnectBuilder(BaseHttpMethod method) {
        super(method);
    }

    @Override
    protected HttpURLConnection build() throws IOException {
        String surl = method.getUrl();

        URL url = new URL(surl);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();

        con.setRequestMethod(method.getMethod());

        return con;

    }

}

5 简单实用

public static void main(String[] args) {

    BaseHttpMethod get = new HttpGet("http://www.jianshu.com");
    DownLoadHttpClient client = DownLoadHttpClient.getInstance();
    try {
        IHttpResponse response = client.exec(get);
        System.out.println(response.getContent());
    } catch (IOException e) {
        e.printStackTrace();
    }

}



输出:
<!DOCTYPE html>
<!--[if IE 6]><html class="ie lt-ie8"><![endif]-->
<!--[if IE 7]><html class="ie lt-ie8"><![endif]-->
<!--[if IE 8]><html class="ie ie8"><![endif]-->
<!--[if IE 9]><html class="ie ie9"><![endif]-->
<!--[if !IE]><!--> <html> <!--<![endif]-->

<head>

。。。。。。。

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值