HttpClient应用 - pingdongyi/blog-2 GitHub Wiki

/**
     * 最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面
     */
    public void test1() throws HttpException, IOException {
        HttpClient client = new HttpClient();
        // 设置代理服务器地址和端口
        // client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);
        // 使用GET方法,如果服务器需要通过HTTPS连接,那只需要将下面URL中的http换成https
        HttpMethod method = new GetMethod("http://java.sun.com");
        // 使用POST方法
        // HttpMethod method = new PostMethod("http://java.sun.com");
        client.executeMethod(method);
        // 打印服务器返回的状态
        System.out.println(method.getStatusLine());
        // 打印返回的信息

        System.out.println(method.getResponseBodyAsString());
        // 释放连接
        method.releaseConnection();

    }

    /**
     * 以GET方式向网页提交参数
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test2() throws HttpException, IOException {
        HttpClient client = new HttpClient();
        client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");

        HttpMethod method = new GetMethod("/simcard.php?simcard=1330227");
        client.executeMethod(method);
        System.out.println(method.getStatusLine());
        // 打印结果页面
        String response = new String(method.getResponseBodyAsString().getBytes("8859_1"));
        // 打印返回的信息
        System.out.println(response);

    }

    /**
     * 使用POST方式提交数据
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test3() throws HttpException, IOException {
        HttpClient client = new HttpClient();
        PostMethod post = new PostMethod("/simcard.php");
        NameValuePair simcard = new NameValuePair("simcard", "1330227");

        post.setRequestBody(new NameValuePair[] { simcard });
        client.executeMethod(post);

    }

    /**
     * 处理页面重定向
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test4() throws HttpException, IOException {
        HttpClient client = new HttpClient();
        PostMethod post = new PostMethod("/simcard.php");
        client.executeMethod(post);

        System.out.println(post.getStatusLine().toString());

        post.releaseConnection();

        // 检查是否重定向

        int statuscode = post.getStatusCode();

        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||

        (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||

        (statuscode == HttpStatus.SC_SEE_OTHER) ||

        (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {

            // 读取新的URL地址

            Header header = post.getResponseHeader("location");

            if (header != null) {

                String newuri = header.getValue();

                if ((newuri == null) || (newuri.equals("")))

                newuri = "/";

                GetMethod redirect = new GetMethod(newuri);

                client.executeMethod(redirect);

                System.out.println("Redirect:" + redirect.getStatusLine().toString());

                redirect.releaseConnection();

            } else

            System.out.println("Invalid redirect");
        }

    }

    /**
     * 提交XML格式参数
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test5() throws HttpException, IOException {
        File input = new File("test.xml");

        PostMethod post = new PostMethod("http://localhost:8080/httpclient/xml.jsp");

        // 设置请求的内容直接从文件中读取

        post.setRequestBody(new FileInputStream(input));

        if (input.length() < Integer.MAX_VALUE)

        post.setRequestContentLength(input.length());

        else post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);

        // 指定请求内容的类型

        post.setRequestHeader("Content-type", "text/xml; charset=GBK");

        HttpClient httpclient = new HttpClient();

        int result = httpclient.executeMethod(post);

        System.out.println("Response status code: " + result);

        System.out.println("Response body: ");

        System.out.println(post.getResponseBodyAsString());

        post.releaseConnection();

    }

    /**
     * 通过HTTP上传文件
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test6() throws HttpException, IOException {
        MultipartPostMethod filePost = new MultipartPostMethod("targetURL");

        filePost.addParameter("fileName", "targetFilePath");

        HttpClient client = new HttpClient();

        // 由于要上传的文件可能比较大,因此在此设置最大的连接超时时间

        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

        int status = client.executeMethod(filePost);

        // 上面代码中,targetFilePath即为要上传的文件所在的路径。

    }

    /**
     * 访问启用认证的页面
     * 我们经常会碰到这样的页面,当访问它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,这种用户认证的方式不同于我们在前面介绍的基于表单的用户身份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括
     * :基本、摘要以及NTLM认证。其中基本认证最简单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式,而NTLM则是微软公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证还要安全的一种方式。
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test7() throws HttpException, IOException {
        HttpClient client = new HttpClient();

        client.getState().setCredentials("www.verisign.com", "realm",
                                         new UsernamePasswordCredentials("username", "password"));

        GetMethod get = new GetMethod("https://www.verisign.com/products/index.html");

        get.setDoAuthentication(true);

        int status = client.executeMethod(get);

        System.out.println(status + "" + get.getResponseBodyAsString());

        get.releaseConnection();

    }

    /**
     * 多线程模式下使用httpclient 多线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection
     * 同一个时间只能有一个线程访问,为了保证多线程工作环境下不产生冲突,httpclient使用了一个多线程连接管理器的类:
     * MultiThreadedHttpConnectionManager,要使用这个类很简单,只需要在构造HttpClient实例的时候传入即可,
     * 使用多线程的主要目的,是为了实现并行的下载。在httpclient运行的过程中,每个http协议的方法
     * ,使用一个HttpConnection实例。由于连接是一种有限的资源,每个连接在某一时刻只能供一个线程和方法使用,所以需要确保在需要时正确地分配连接
     * 。HttpClient采用了一种类似jdbc连接池的方法来管理连接,这个管理工作由 MultiThreadedHttpConnectionManager完成。 client可以在多个线程中被用来执行多个方法。每次调用
     * HttpClient.executeMethod() 方法,都会去链接管理器申请一个连接实例,申请成功这个链接实例被签出(checkout),随之在链接使用完后必须归还管理器。管理器支持两个设置:
     * maxConnectionsPerHost 每个主机的最大并行链接数,默认为2 maxTotalConnections 客户端总并行链接最大数,默认为20
     * 由于是使用HttpClient的程序而不是HttpClient本身来读取应答包的主体
     * ,所以HttpClient无法决定什么时间连接不再使用了,这也就要求在读完应答包的主体后必须手工显式地调用releaseConnection()来释放申请的链接。
     * 
     * @throws IOException
     * @throws HttpException
     */
    public void test8() throws HttpException, IOException {

        MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
        HttpClient client = new HttpClient(connectionManager);
        // 在某个线程中。
        GetMethod get = new GetMethod("http://jakarta.apache.org/");
        try {
            client.executeMethod(get);
            // print response to stdout
            System.out.println(get.getResponseBodyAsStream());
        } finally {
            // be sure the connection is released back to the connection
            // manager
            get.releaseConnection();
        }
        // 对每一个HttpClient.executeMethod须有一个method.releaseConnection()与之匹配.

    }
⚠️ **GitHub.com Fallback** ⚠️