自己写的简单HttpClient

作者: 奔跑的笨鸟 | 来源:发表于2016-05-18 17:28 被阅读551次

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

    1 定义一个抽象BaseHttpMethod类

    <pre>
    `
    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;
    }
    

    }
    `
    </pre>

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

    <pre>
    `
    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);
    }
    

    }
    `
    </pre>
    其他2个HttpGet,HttpHead和这个差不多

    2 定义一个Response 接口IHttpResponse

    <pre>
    `
    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();
    

    }
    `
    </pre>
    HttpResponse简单实现了这个接口

    <pre>
    `
    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();
    }
    

    }
    `
    </pre>

    3 简单定义一个HttpClient

    <pre>
    `
    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);
    }
    

    }
    `
    </pre>

    这里用到一个ConnectFactory 来获得URLHttpConnection

    4 一个简单ConnectFactory

    <pre>
    `
    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);
    }
    

    }
    </pre> 在这个工厂方法中用到了一个Builder, 其中的抽象类为: <pre>
    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();
    }
    

    }
    </pre> 其中的HeadConnectBuilder <pre>
    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;
    
    }
    

    }
    `
    </pre>

    5 简单实用

    <pre>
    <code>
    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();
        }
        
    }
    

    </code>
    </pre>
    输出:
    <!DOCTYPE html>




    <html>

    <head>

    。。。。。。。

    </html>

    相关文章

      网友评论

        本文标题:自己写的简单HttpClient

        本文链接:https://www.haomeiwen.com/subject/aiywrttx.html