httpclient 订阅
HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。 展开全文
HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
信息
所属项目
Apache Jakarta Common
支持版本
HTTP 协议最新的版本和建议
外文名
httpclient
中文名
httpclient
性    质
客户端编程工具包
httpclient简介
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 .6(2015-09-11)
收起全文
精华内容
参与话题
问答
  • HTTPClientHttpClient框架详解

    千次阅读 2016-12-24 15:42:08
    HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本...


    HttpClient简介

    HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。更多信息请关注http://hc.apache.org/

     

    HttpClient 功能介绍

    以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。

    • 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)

    • 支持自动转向

    • 支持 HTTPS 协议

    • 支持代理服务器等

    应用HttpClient来对付各种顽固的WEB服务器
    转自:http://blog.csdn.net/ambitiontan/archive/2006/01/06/572171.aspx

    一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等。所访问的这些页面有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需要认证以及是一些通过加密方式传输,例如HTTPS。目前我们使用的浏览器处理这些情况都不会构成问题。不过你可能在某些时候需要通过程序来访问这样的一些页面,比如从别人的网页中“偷”一些数据;利用某些站点提供的页面来完成某种功能,例如说我们想知道某个手机号码的归属地而我们自己又没有这样的数据,因此只好借助其他公司已有的网站来完成这个功能,这个时候我们需要向网页提交手机号码并从返回的页面中解析出我们想要的数据来。如果对方仅仅是一个很简单的页面,那我们的程序会很简单,本文也就没有必要大张旗鼓的在这里浪费口舌。但是考虑到一些服务授权的问题,很多公司提供的页面往往并不是可以通过一个简单的URL就可以访问的,而必须经过注册然后登录后方可使用提供服务的页面,这个时候就涉及到COOKIE问题的处理。我们知道目前流行的动态网页技术例如ASP、JSP无不是通过COOKIE来处理会话信息的。为了使我们的程序能使用别人所提供的服务页面,就要求程序首先登录后再访问服务页面,这过程就需要自行处理cookie,想想当你用java.net.HttpURLConnection来完成这些功能时是多么恐怖的事情啊!况且这仅仅是我们所说的顽固的WEB服务器中的一个很常见的“顽固”!再有如通过HTTP来上传文件呢?不需要头疼,这些问题有了“它”就很容易解决了!

     

    我们不可能列举所有可能的顽固,我们会针对几种最常见的问题进行处理。当然了,正如前面说到的,如果我们自己使用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情,因此在开始之前我们先要介绍一下一个开放源码的项目,这个项目就是Apache开源组织中的httpclient,它隶属于Jakarta的commons项目,目前的版本是2.0RC2。commons下本来已经有一个net的子项目,但是又把httpclient单独提出来,可见http服务器的访问绝非易事。

    Commons-httpclient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。通过它可以让原来很头疼的事情现在轻松的解决,例如你不再管是HTTP或者HTTPS的通讯方式,告诉它你想使用HTTPS方式,剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时经常碰到的几个问题进行分别介绍如何使用httpclient来解决它们,为了让读者更快的熟悉这个项目我们最开始先给出一个简单的例子来读取一个网页的内容,然后循序渐进解决掉前进中的所有问题。

     

    1. 读取网页(HTTP/HTTPS)内容

    下面是我们给出的一个简单的例子用来访问某个页面

    复制代码
    /** 
     *最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面
      *@authorLiudong
    */
    public class SimpleClient {
    public static void main(String[] args) throws 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();
       }
    }
    复制代码

     

    在这个例子中首先创建一个HTTP客户端(HttpClient)的实例,然后选择提交的方法是GET或者POST,最后在HttpClient实例上执行提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。其实用一行代码也就可以搞定整个请求的过程,非常的简单!

     

    2、使用POST方式提交数据(httpClient3)

    httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可,下面这里将给出关于两种模拟上传方式的代码

     

    第一种:模拟上传url文件(该方式也适合做普通post请求):

    复制代码
    /**
         * 上传url文件到指定URL
         * @param fileUrl 上传图片url
         * @param postUrl 上传路径及参数,注意有些中文参数需要使用预先编码 eg : URLEncoder.encode(appName, "UTF-8")
         * @return
         * @throws IOException
         */
        public static String doUploadFile(String postUrl) throws IOException {
            if(StringUtils.isEmpty(postUrl))
                return null;
            String response = "";
            PostMethod postMethod = new PostMethod(postUrl);
            try {
                HttpClient client = new HttpClient();
                client.getHttpConnectionManager().getParams()
                        .setConnectionTimeout(50000);// 设置连接时间
                int status = client.executeMethod(postMethod);
                if (status == HttpStatus.SC_OK) {
                    InputStream inputStream = postMethod.getResponseBodyAsStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            inputStream));
                    StringBuffer stringBuffer = new StringBuffer();
                    String str = "";
                    while ((str = br.readLine()) != null) {
                        stringBuffer.append(str);
                    }
                    response = stringBuffer.toString();
                } else {
                    response = "fail";
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放连接
                postMethod.releaseConnection();
            }
            return response;
        }
    复制代码

     

     

    第二种:模拟文件上传到指定位置

     

    复制代码
    /**
         * 上传文件到指定URL
         * @param file
         * @param url
         * @return
         * @throws IOException
         */
        public static String doUploadFile(File file, String url) throws IOException {
            String response = "";
            if (!file.exists()) {
                return "file not exists";
            }
            PostMethod postMethod = new PostMethod(url);
            try {
                //----------------------------------------------
                // FilePart:用来上传文件的类,file即要上传的文件
                FilePart fp = new FilePart("file", file);
                Part[] parts = { fp };
    
                // 对于MIME类型的请求,httpclient建议全用MulitPartRequestEntity进行包装
                MultipartRequestEntity mre = new MultipartRequestEntity(parts,
                        postMethod.getParams());
                postMethod.setRequestEntity(mre);
                //---------------------------------------------
                HttpClient client = new HttpClient();
                client.getHttpConnectionManager().getParams()
                        .setConnectionTimeout(50000);// 由于要上传的文件可能比较大 , 因此在此设置最大的连接超时时间
                int status = client.executeMethod(postMethod);
                if (status == HttpStatus.SC_OK) {
                    InputStream inputStream = postMethod.getResponseBodyAsStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            inputStream));
                    StringBuffer stringBuffer = new StringBuffer();
                    String str = "";
                    while ((str = br.readLine()) != null) {
                        stringBuffer.append(str);
                    }
                    response = stringBuffer.toString();
                } else {
                    response = "fail";
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放连接
                postMethod.releaseConnection();
            }
            return response;
        }
    复制代码

     

     

    3. 处理页面重定向

    在JSP/Servlet编程中response.sendRedirect方法就是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward …>的区别在于后者是在服务器中实现页面的跳转,也就是说应用容器加载了所要跳转的页面的内容并返回给客户端;而前者是返回一个状态码,这些状态码的可能值见下表,然后客户端读取需要跳转到的页面的URL并重新加载新的页面。就是这样一个过程,所以我们编程的时候就要通过HttpMethod.getStatusCode()方法判断返回值是否为下表中的某个值来判断是否需要跳转。如果已经确认需要进行页面跳转了,那么可以通过读取HTTP头中的location属性来获取新的地址。

     


    下面的代码片段演示如何处理页面的重定向

    复制代码
    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){
          Stringnewuri=header.getValue();
          if((newuri==null)||(newuri.equals("")))
             newuri="/";
             GetMethodredirect=newGetMethod(newuri);
             client.executeMethod(redirect);
             System.out.println("Redirect:"+redirect.getStatusLine().toString());
             redirect.releaseConnection();
       }else 
        System.out.println("Invalid redirect");
    }
    复制代码

     

     

    我们可以自行编写两个JSP页面,其中一个页面用response.sendRedirect方法重定向到另外一个页面用来测试上面的例子。

     

    4. 模拟登录开心网

    本小节应该说是HTTP客户端编程中最常碰见的问题,很多网站的内容都只是对注册用户可见的,这种情况下就必须要求使用正确的用户名和口令登录成功后,方可浏览到想要的页面。因为HTTP协议是无状态的,也就是连接的有效期只限于当前请求,请求内容结束后连接就关闭了。在这种情况下为了保存用户的登录信息必须使用到Cookie机制。以JSP/Servlet为例,当浏览器请求一个JSP或者是Servlet的页面时,应用服务器会返回一个参数,名为jsessionid(因不同应用服务器而异),值是一个较长的唯一字符串的Cookie,这个字符串值也就是当前访问该站点的会话标识。浏览器在每访问该站点的其他页面时候都要带上jsessionid这样的Cookie信息,应用服务器根据读取这个会话标识来获取对应的会话信息。

    对于需要用户登录的网站,一般在用户登录成功后会将用户资料保存在服务器的会话中,这样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息,然后就可以判断用户资料是否存在于会话信息中,如果存在则允许访问页面,否则跳转到登录页面中要求用户输入帐号和口令进行登录。这就是一般使用JSP开发网站在处理用户登录的比较通用的方法。

    这样一来,对于HTTP的客户端来讲,如果要访问一个受保护的页面时就必须模拟浏览器所做的工作,首先就是请求登录页面,然后读取Cookie值;再次请求登录页面并加入登录页所需的每个参数;最后就是请求最终所需的页面。当然在除第一次请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前请求是否已经通过验证。说了这么多,可是如果你使用httpclient的话,你甚至连一行代码都无需增加,你只需要先传递登录信息执行登录过程,然后直接访问想要的页面,跟访问一个普通的页面没有任何区别,因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实现了模拟登陆开心网并向自己好友发送消息的功能。

     

    复制代码
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    import org.apache.commons.httpclient.Cookie;
    import org.apache.commons.httpclient.Header;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpStatus;
    import org.apache.commons.httpclient.NameValuePair;
    import org.apache.commons.httpclient.cookie.CookiePolicy;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.methods.PostMethod;
    import org.apache.commons.httpclient.params.HttpClientParams;
    import org.apache.commons.httpclient.params.HttpMethodParams;
    
    class Login {
        public static String loginurl = "https://security.kaixin001.com/login/login_post.php";
        static Cookie[] cookies = {};
    
        static HttpClient httpClient = new HttpClient();
        
        static String email = "xxx@qq.com";//你的email
        static String psw = "xxx";//你的密码
        // 消息发送的action
        String url = "http://www.kaixin001.com/home/";
    
        public static void getUrlContent()
                throws Exception {
    
            HttpClientParams httparams = new HttpClientParams();
            httparams.setSoTimeout(30000);
            httpClient.setParams(httparams);
    
            httpClient.getHostConfiguration().setHost("www.kaixin001.com", 80);
    
            httpClient.getParams().setParameter(
                    HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
    
            PostMethod login = new PostMethod(loginurl);
            login.addRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=UTF-8");
    
            NameValuePair Email = new NameValuePair("loginemail", email);// 邮箱
            NameValuePair password = new NameValuePair("password", psw);// 密码
            // NameValuePair code = new NameValuePair( "code"
            // ,"????");//有时候需要验证码,暂时未解决
    
            NameValuePair[] data = { Email, password };
            login.setRequestBody(data);
    
            httpClient.executeMethod(login);
            int statuscode = login.getStatusCode();
            System.out.println(statuscode + "-----------");
            String result = login.getResponseBodyAsString();
            System.out.println(result+"++++++++++++");
    
            cookies = httpClient.getState().getCookies();
            System.out.println("==========Cookies============");
            int i = 0;
            for (Cookie c : cookies) {
                System.out.println(++i + ":   " + c);
            }
            httpClient.getState().addCookies(cookies);
    
            // 当state为301或者302说明登陆页面跳转了,登陆成功了
            if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY)
                    || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY)
                    || (statuscode == HttpStatus.SC_SEE_OTHER)
                    || (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
                // 读取新的 URL 地址
                Header header = login.getResponseHeader("location");
                // 释放连接
                login.releaseConnection();
                System.out.println("获取到跳转header>>>" + header);
                if (header != null) {
                    String newuri = header.getValue();
                    if ((newuri == null) || (newuri.equals("")))
                        newuri = "/";
                    GetMethod redirect = new GetMethod(newuri);
                    // 
                    redirect.setRequestHeader("Cookie", cookies.toString());
                    httpClient.executeMethod(redirect);
                    System.out.println("Redirect:"
                            + redirect.getStatusLine().toString());
                    redirect.releaseConnection();
    
                } else
                    System.out.println("Invalid redirect");
            } else {
                // 用户名和密码没有被提交,当登陆多次后需要验证码的时候会出现这种未提交情况
                System.out.println("用户没登陆");
                System.exit(1);
            }
    
        }
    
        public static void sendMsg() throws Exception {
            // 登录后发消息
            System.out.println("*************发消息***********");
    
            String posturl = "http://www.kaixin001.com/msg/post.php";
            PostMethod poster = new PostMethod(posturl);
    
            poster.addRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=UTF-8");
            poster.setRequestHeader("Cookie", cookies.toString());
    
            NameValuePair uids = new NameValuePair("uids", "89600585");// 发送的好友对象的id,此处换成你的好友id
            NameValuePair content = new NameValuePair("content", "你好啊!");// 需要发送的信息的内容
            NameValuePair liteeditor_0 = new NameValuePair("liteeditor_0", "你好啊!");// 需要发送的信息的内容
            NameValuePair texttype = new NameValuePair("texttype", "plain");
            NameValuePair send_separate = new NameValuePair("send_separate", "0");
            NameValuePair service = new NameValuePair("service", "0");
            NameValuePair[] msg = { uids, content, texttype, send_separate, service,liteeditor_0 };
    
            poster.setRequestBody(msg);
            httpClient.executeMethod(poster);
    
            String result = poster.getResponseBodyAsString();
            System.out.println(result+"++++++++++++");
            //System.out.println(StreamOut(result, "iso8859-1"));
            int statuscode = poster.getStatusCode();
            System.out.println(statuscode + "-----------");
            if(statuscode == 301 || statuscode == 302){
                // 读取新的 URL 地址
                Header header = poster.getResponseHeader("location");
                System.out.println("获取到跳转header>>>" + header);
                if (header != null) {
                    String newuri = header.getValue();
                    if ((newuri == null) || (newuri.equals("")))
                        newuri = "/";
                    GetMethod redirect = new GetMethod(newuri);
                    // 
                    redirect.setRequestHeader("Cookie", cookies.toString());
                    httpClient.executeMethod(redirect);
                    System.out.println("Redirect:"
                            + redirect.getStatusLine().toString());
                    redirect.releaseConnection();
    
                } else
                    System.out.println("Invalid redirect");
            }
            
                poster.releaseConnection();
        }
    
        public static String StreamOut(InputStream txtis, String code)
                throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(txtis,
                    code));
            String tempbf;
            StringBuffer html = new StringBuffer(100);
            while ((tempbf = br.readLine()) != null) {
                html.append(tempbf + "\n");
            }
            return html.toString();
    
        }
    }
    复制代码

     

     

    5. 提交XML格式参数

    提交XML格式的参数很简单,仅仅是一个提交时候的ContentType问题,下面的例子演示从文件文件中读取XML信息并提交给服务器的过程,该过程可以用来测试Web服务。

    复制代码
    import java.io.File; 
    import java.io.FileInputStream; 
    import org.apache.commons.httpclient.HttpClient; 
    import org.apache.commons.httpclient.methods.EntityEnclosingMethod; 
    import org.apache.commons.httpclient.methods.PostMethod;
    /** 
     *用来演示提交XML格式数据的例子
    */
    public class PostXMLClient {
    
       public static void main(String[] args) throws Exception {
          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(); 
       } 
    }
    复制代码

     

     

    6. 访问启用认证的页面

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

    下面例子是从httpclient的CVS服务器中下载的,它简单演示如何访问一个认证保护的页面:

    复制代码
    import org.apache.commons.httpclient.HttpClient; 
    import org.apache.commons.httpclient.UsernamePasswordCredentials; 
    import org.apache.commons.httpclient.methods.GetMethod; 
    
    public class BasicAuthenticationExample { 
    
       public BasicAuthenticationExample() { 
       }
    
       public static void main(String[] args) throws Exception {
          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+ "\n" + get.getResponseBodyAsString());
          get.releaseConnection();
       } 
    }
    复制代码

     

     

    7. 多线程模式下使用

    多线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问,为了保证多线程工作环境下不产生冲突,httpclient使用了一个多线程连接管理器的类:MultiThreadedHttpConnectionManager,要使用这个类很简单,只需要在构造HttpClient实例的时候传入即可,代码如下:

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

    HttpClient client = new HttpClient(connectionManager);

    以后尽管访问client实例即可。

     

    httpClient完整封装

    HttpInvoke.java:封装了HttpClient调度的必要参数设置,以及post,get等常用方法

    复制代码
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.commons.httpclient.*;
    import org.apache.commons.httpclient.auth.AuthScope;
    import org.apache.commons.httpclient.methods.PostMethod;
    import org.apache.commons.httpclient.methods.GetMethod;
    
    import java.util.Iterator;
    import java.util.Map;
    import java.net.SocketTimeoutException;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class HttpInvoker {
        private Log logger = LogFactory.getLog(HttpInvoker.class);
        private static HttpInvoker httpInvoker = new HttpInvoker();
        private HttpClient client = null;
        private String charset = "gbk";
        private int timeout = 10000;
        private boolean useProxy = false;
        private String proxyHost = null;
        private int proxyPort;
        private String proxyUsername = null;
        private String proxyPassword = null;
        private boolean initialized = false;
        
        public static HttpInvoker getInstance() {
            return httpInvoker;
        }
    
        private HttpInvoker() {
            client = new HttpClient(new MultiThreadedHttpConnectionManager());
            client.getParams().setParameter("http.protocol.content-charset", "gbk");
            client.getParams().setContentCharset("gbk");
            client.getParams().setSoTimeout(timeout);
        }
    
        public HttpInvoker(String charset, int timeout, boolean useProxy,
                           String proxyHost, int proxyPort, String proxyUsername,
                           String proxyPassword) {
            client = new HttpClient(new MultiThreadedHttpConnectionManager());
            if(charset != null && !charset.trim().equals("")) {
                this.charset = charset;
            }
            if(timeout > 0) {
                this.timeout = timeout;
            }
            client.getParams().setParameter("http.protocol.content-charset", charset);
            client.getParams().setContentCharset(charset);
            client.getParams().setSoTimeout(timeout);
            if(useProxy && proxyHost != null &&
                    !proxyHost.trim().equals("") && proxyPort > 0) {
                HostConfiguration hc = new HostConfiguration();
                hc.setProxy(proxyHost, proxyPort);
                client.setHostConfiguration(hc);
                if (proxyUsername != null && !proxyUsername.trim().equals("") &&
                        proxyPassword != null && !proxyPassword.trim().equals("")) {
                    client.getState().setProxyCredentials(AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUsername, proxyPassword));
                }
            }
            initialized = true;
            logger.debug("HttpInvoker初始化完成");
        }
    
        public synchronized void init() {
            if(charset != null && !charset.trim().equals("")) {
                client.getParams().setParameter("http.protocol.content-charset", charset);
                client.getParams().setContentCharset(charset);
            }
            if(timeout > 0) {
                client.getParams().setSoTimeout(timeout);
            }
            if(useProxy && proxyHost != null &&
                    !proxyHost.trim().equals("") && proxyPort > 0) {
                HostConfiguration hc = new HostConfiguration();
                hc.setProxy(proxyHost, proxyPort);
                client.setHostConfiguration(hc);
                if (proxyUsername != null && !proxyUsername.trim().equals("") &&
                        proxyPassword != null && !proxyPassword.trim().equals("")) {
                    client.getState().setProxyCredentials(AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUsername, proxyPassword));
                }
            }
            initialized = true;
            logger.debug("HttpInvoker初始化完成");
        }
    
        public String invoke(String url) throws Exception {
            return invoke(url, null, false);
        }
    
        public String invoke(String url, Map params, boolean isPost) throws Exception {
            logger.debug("HTTP调用[" + (isPost?"POST":"GET") + "][" + url + "][" + params + "]");
            HttpMethod httpMethod = null;
            String result = "";
            try {
                if(isPost && params != null && params.size() > 0) {
                    Iterator paramKeys = params.keySet().iterator();
                    httpMethod = new PostMethod(url);
                    NameValuePair[] form = new NameValuePair[params.size()];
                    int formIndex = 0;
                    while(paramKeys.hasNext()) {
                        String key = (String)paramKeys.next();
                        Object value = params.get(key);
                        if(value != null && value instanceof String && !value.equals("")) {
                            form[formIndex] = new NameValuePair(key, (String)value);
                            formIndex++;
                        } else if(value != null && value instanceof String[] &&
                                ((String[])value).length > 0) {
                            NameValuePair[] tempForm =
                                    new NameValuePair[form.length + ((String[])value).length - 1];
                            for(int i=0; i<formIndex; i++) {
                                tempForm[i] = form[i];
                            }
                            form = tempForm;
                            for(String v : (String[])value) {
                                form[formIndex] = new NameValuePair(key, (String)v);
                                formIndex++;
                            }
                        }
                    }
                    ((PostMethod)httpMethod).setRequestBody(form);
                } else {
                    if(params != null && params.size() > 0) {
                        Iterator paramKeys = params.keySet().iterator();
                        StringBuffer getUrl = new StringBuffer(url.trim());
                        if(url.trim().indexOf("?") > -1) {
                            if(url.trim().indexOf("?") < url.trim().length()-1 &&
                                    url.trim().indexOf("&")  < url.trim().length()-1) {
                                getUrl.append("&");
                            }
                        } else {
                            getUrl.append("?");
                        }
                        while(paramKeys.hasNext()) {
                            String key = (String)paramKeys.next();
                            Object value = params.get(key);
                            if(value != null && value instanceof String && !value.equals("")) {
                                getUrl.append(key).append("=").append(value).append("&");
                            } else if(value != null && value instanceof String[] &&
                                    ((String[])value).length > 0) {
                                for(String v : (String[])value) {
                                    getUrl.append(key).append("=").append(v).append("&");
                                }
                            }
                        }
                        if(getUrl.lastIndexOf("&") == getUrl.length()-1) {
                            httpMethod = new GetMethod(getUrl.substring(0, getUrl.length()-1));
                        } else {
                            httpMethod = new GetMethod(getUrl.toString());
                        }
                    } else {
                        httpMethod = new GetMethod(url);
                    }
                }
                client.executeMethod(httpMethod);
    //            result = httpMethod.getResponseBodyAsString();
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        httpMethod.getResponseBodyAsStream(),"ISO-8859-1"));
                String line = null;
                String html = null;
                while((line = reader.readLine()) != null){
                    if(html == null) {
                        html = "";
                    } else {
                        html += "\r\n";
                    }
                    html += line;
                }
                if(html != null) {
                    result = new String(html.getBytes("ISO-8859-1"), charset);
                }
            } catch (SocketTimeoutException e) {
                logger.error("连接超时[" + url + "]");
                throw e;
            } catch (java.net.ConnectException e) {
                logger.error("连接失败[" + url + "]");
                throw e;
            } catch (Exception e) {
                logger.error("连接时出现异常[" + url + "]");
                throw e;
            } finally {
                if (httpMethod != null) {
                    try {
                        httpMethod.releaseConnection();
                    } catch (Exception e) {
                        logger.error("释放网络连接失败[" + url + "]");
                        throw e;
                    }
                }
            }
    
            return result;
        }
    
        public void setCharset(String charset) {
            this.charset = charset;
        }
    
        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }
    
        public void setProxyHost(String proxyHost) {
            this.proxyHost = proxyHost;
        }
    
        public void setProxyPort(int proxyPort) {
            this.proxyPort = proxyPort;
        }
    
        public void setProxyUsername(String proxyUsername) {
            this.proxyUsername = proxyUsername;
        }
    
        public void setProxyPassword(String proxyPassword) {
            this.proxyPassword = proxyPassword;
        }
    
        public void setUseProxy(boolean useProxy) {
            this.useProxy = useProxy;
        }
    
        public synchronized boolean isInitialized() {
            return initialized;
        }
    }
    复制代码

     

    http访问网络的代理ip和端口,还有使用用户及密码都可以在Spring容器中注入进来:

    复制代码
    <bean id="httpInvoker" class="HttpInvoker">
            <constructor-arg type="java.lang.String" value="gbk" /><!--useProxy-->
            <constructor-arg type="int" value="10000" /><!--useProxy-->
            <constructor-arg type="boolean" value="true" /><!--useProxy-->
            <!--代理地址 -->
            <constructor-arg type="java.lang.String" value="192.168.1.1" />
            <constructor-arg type="int" value="8080" />
            <constructor-arg type="java.lang.String" value="" /><!--用户名-->
            <constructor-arg type="java.lang.String" value="" /><!--密码-->
    </bean>
    复制代码

     

     

    使用方式:post

    Map<String,String> params = new HashMap<String,String>();
    params.put("check", check);
    String result = httpInvoker.invoke( "someURL", params, true);

    使用方式:get

    String content  = httpInvoker.invoke(url);

     

    参考资料:

    httpclient首页:    http://jakarta.apache.org/commons/httpclient/
    关于NTLM是如何工作:  http://davenport.sourceforge.net/ntlm.html


    --------------------------------------------

    HttpClient入门
    http://blog.csdn.net/ambitiontan/archive/2006/01/07/572644.aspx

    Jakarta Commons HttpClient 学习笔记
    http://blog.csdn.net/cxl34/archive/2005/01/19/259051.aspx

    Cookies,SSL,httpclient的多线程处理,HTTP方法
    http://blog.csdn.net/bjbs_270/archive/2004/11/05/168233.aspx

    展开全文
  • HttpClient详细使用示例

    万次阅读 多人点赞 2018-07-14 12:11:04
    HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中...HttpClient 是 Apache Jakarta Common 下的子项目,用...

            HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

            HTTP和浏览器有点像,但却不是浏览器。很多人觉得既然HttpClient是一个HTTP客户端编程工具,很多人把他当做浏览器来理解,但是其实HttpClient不是浏览器,它是一个HTTP通信库,因此它只提供一个通用浏览器应用程序所期望的功能子集,最根本的区别是HttpClient中没有用户界面,浏览器需要一个渲染引擎来显示页面,并解释用户输入,例如鼠标点击显示页面上的某处,有一个布局引擎,计算如何显示HTML页面,包括级联样式表和图像。javascript解释器运行嵌入HTML页面或从HTML页面引用的javascript代码。来自用户界面的事件被传递到javascript解释器进行处理。除此之外,还有用于插件的接口,可以处理Applet,嵌入式媒体对象(如pdf文件,Quicktime电影和Flash动画)或ActiveX控件(可以执行任何操作)。HttpClient只能以编程的方式通过其API用于传输和接受HTTP消息。

    HttpClient的主要功能:

    • 实现了所有 HTTP 的方法(GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS 等)
    • 支持 HTTPS 协议
    • 支持代理服务器(Nginx等)等
    • 支持自动(跳转)转向
    • ……

    进入正题


    环境说明:JDK1.8、SpringBoot

    准备环节

    第一步:在pom.xml中引入HttpClient的依赖

    第二步:引入fastjson依赖

    注:本人引入此依赖的目的是,在后续示例中,会用到“将对象转化为json字符串的功能”,也可以引其他有此功能的依赖。 

    注:SpringBoot的基本依赖配置,这里就不再多说了。


    详细使用示例

    声明:此示例中,以JAVA发送HttpClient(在test里面单元测试发送的);也是以JAVA接收的(在controller里面接收的)。

    声明:下面的代码,本人亲测有效。

    GET无参

    HttpClient发送示例:

        /**
    	 * GET---无参测试
    	 *
    	 * @date 2018年7月13日 下午4:18:50
    	 */
    	@Test
    	public void doGetTestOne() {
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    		// 创建Get请求
    		HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerOne");
    
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 由客户端执行(发送)Get请求
    			response = httpClient.execute(httpGet);
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:

    GET有参(方式一:直接拼接URL)

    HttpClient发送示例:

        /**
    	 * GET---有参测试 (方式一:手动在url后面加上参数)
    	 *
    	 * @date 2018年7月13日 下午4:19:23
    	 */
    	@Test
    	public void doGetTestWayOne() {
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    
    		// 参数
    		StringBuffer params = new StringBuffer();
    		try {
    			// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
    			params.append("name=" + URLEncoder.encode("&", "utf-8"));
    			params.append("&");
    			params.append("age=24");
    		} catch (UnsupportedEncodingException e1) {
    			e1.printStackTrace();
    		}
    
    		// 创建Get请求
    		HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerTwo" + "?" + params);
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 配置信息
    			RequestConfig requestConfig = RequestConfig.custom()
    					// 设置连接超时时间(单位毫秒)
    					.setConnectTimeout(5000)
    					// 设置请求超时时间(单位毫秒)
    					.setConnectionRequestTimeout(5000)
    					// socket读写超时时间(单位毫秒)
    					.setSocketTimeout(5000)
    					// 设置是否允许重定向(默认为true)
    					.setRedirectsEnabled(true).build();
    
    			// 将上面的配置信息 运用到这个Get请求里
    			httpGet.setConfig(requestConfig);
    
    			// 由客户端执行(发送)Get请求
    			response = httpClient.execute(httpGet);
    
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:

    GET有参(方式二:使用URI获得HttpGet)

    HttpClient发送示例:

        /**
    	 * GET---有参测试 (方式二:将参数放入键值对类中,再放入URI中,从而通过URI得到HttpGet实例)
    	 *
    	 * @date 2018年7月13日 下午4:19:23
    	 */
    	@Test
    	public void doGetTestWayTwo() {
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    
    		// 参数
    		URI uri = null;
    		try {
    			// 将参数放入键值对类NameValuePair中,再放入集合中
    			List<NameValuePair> params = new ArrayList<>();
    			params.add(new BasicNameValuePair("name", "&"));
    			params.add(new BasicNameValuePair("age", "18"));
    			// 设置uri信息,并将参数集合放入uri;
    			// 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
    			uri = new URIBuilder().setScheme("http").setHost("localhost")
    					              .setPort(12345).setPath("/doGetControllerTwo")
    					              .setParameters(params).build();
    		} catch (URISyntaxException e1) {
    			e1.printStackTrace();
    		}
    		// 创建Get请求
    		HttpGet httpGet = new HttpGet(uri);
    
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 配置信息
    			RequestConfig requestConfig = RequestConfig.custom()
    					// 设置连接超时时间(单位毫秒)
    					.setConnectTimeout(5000)
    					// 设置请求超时时间(单位毫秒)
    					.setConnectionRequestTimeout(5000)
    					// socket读写超时时间(单位毫秒)
    					.setSocketTimeout(5000)
    					// 设置是否允许重定向(默认为true)
    					.setRedirectsEnabled(true).build();
    
    			// 将上面的配置信息 运用到这个Get请求里
    			httpGet.setConfig(requestConfig);
    
    			// 由客户端执行(发送)Get请求
    			response = httpClient.execute(httpGet);
    
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:

    POST无参

    HttpClient发送示例:

        /**
    	 * POST---无参测试
    	 *
    	 * @date 2018年7月13日 下午4:18:50
    	 */
    	@Test
    	public void doPostTestOne() {
    
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    
    		// 创建Post请求
    		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerOne");
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 由客户端执行(发送)Post请求
    			response = httpClient.execute(httpPost);
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:

    POST有参(普通参数)

    注:POST传递普通参数时,方式与GET一样即可,这里以直接在url后缀上参数的方式示例。

    HttpClient发送示例:

        /**
    	 * POST---有参测试(普通参数)
    	 *
    	 * @date 2018年7月13日 下午4:18:50
    	 */
    	@Test
    	public void doPostTestFour() {
    
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    
    		// 参数
    		StringBuffer params = new StringBuffer();
    		try {
    			// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
    			params.append("name=" + URLEncoder.encode("&", "utf-8"));
    			params.append("&");
    			params.append("age=24");
    		} catch (UnsupportedEncodingException e1) {
    			e1.printStackTrace();
    		}
    
    		// 创建Post请求
    		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerFour" + "?" + params);
    
    		// 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
    		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 由客户端执行(发送)Post请求
    			response = httpClient.execute(httpPost);
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:

    POST有参(对象参数)

    先给出User类

    HttpClient发送示例:

    	/**
    	 * POST---有参测试(对象参数)
    	 *
    	 * @date 2018年7月13日 下午4:18:50
    	 */
    	@Test
    	public void doPostTestTwo() {
    
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    
    		// 创建Post请求
    		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerTwo");
    		User user = new User();
    		user.setName("潘晓婷");
    		user.setAge(18);
    		user.setGender("女");
    		user.setMotto("姿势要优雅~");
    		// 我这里利用阿里的fastjson,将Object转换为json字符串;
    		// (需要导入com.alibaba.fastjson.JSON包)
    		String jsonString = JSON.toJSONString(user);
    
    		StringEntity entity = new StringEntity(jsonString, "UTF-8");
    
    		// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
    		httpPost.setEntity(entity);
    
    		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 由客户端执行(发送)Post请求
    			response = httpClient.execute(httpPost);
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:

    POST有参(普通参数 + 对象参数)

    注:POST传递普通参数时,方式与GET一样即可,这里以通过URI获得HttpPost的方式为例。

    先给出User类:

    HttpClient发送示例:

    	/**
    	 * POST---有参测试(普通参数 + 对象参数)
    	 *
    	 * @date 2018年7月13日 下午4:18:50
    	 */
    	@Test
    	public void doPostTestThree() {
    
    		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    
    		// 创建Post请求
    		// 参数
    		URI uri = null;
    		try {
    			// 将参数放入键值对类NameValuePair中,再放入集合中
    			List<NameValuePair> params = new ArrayList<>();
    			params.add(new BasicNameValuePair("flag", "4"));
    			params.add(new BasicNameValuePair("meaning", "这是什么鬼?"));
    			// 设置uri信息,并将参数集合放入uri;
    			// 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
    			uri = new URIBuilder().setScheme("http").setHost("localhost").setPort(12345)
    					.setPath("/doPostControllerThree").setParameters(params).build();
    		} catch (URISyntaxException e1) {
    			e1.printStackTrace();
    		}
    
    		HttpPost httpPost = new HttpPost(uri);
    		// HttpPost httpPost = new
    		// HttpPost("http://localhost:12345/doPostControllerThree1");
    
    		// 创建user参数
    		User user = new User();
    		user.setName("潘晓婷");
    		user.setAge(18);
    		user.setGender("女");
    		user.setMotto("姿势要优雅~");
    
    		// 将user对象转换为json字符串,并放入entity中
    		StringEntity entity = new StringEntity(JSON.toJSONString(user), "UTF-8");
    
    		// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
    		httpPost.setEntity(entity);
    
    		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    
    		// 响应模型
    		CloseableHttpResponse response = null;
    		try {
    			// 由客户端执行(发送)Post请求
    			response = httpClient.execute(httpPost);
    			// 从响应模型中获取响应实体
    			HttpEntity responseEntity = response.getEntity();
    
    			System.out.println("响应状态为:" + response.getStatusLine());
    			if (responseEntity != null) {
    				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    			}
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 释放资源
    				if (httpClient != null) {
    					httpClient.close();
    				}
    				if (response != null) {
    					response.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}

    对应接收示例:


    对评论区关注度较高的问题进行相关补充

    提示:如果想要知道完整的具体的代码及测试细节,可去下面给的项目代码托管链接,将项目clone下来
               进行观察。如果需要运行测试,可以先启动该SpringBoot项目,然后再运行相关test方法,进行
               测试。

    解决响应乱码问题(示例)

    进行HTTPS请求并进行(或不进行)证书校验(示例)

    使用示例:

    相关方法详情(非完美封装):

    /**
     * 根据是否是https请求,获取HttpClient客户端
     *
     * TODO 本人这里没有进行完美封装。对于 校不校验校验证书的选择,本人这里是写死
     *      在代码里面的,你们在使用时,可以灵活二次封装。
     *
     * 提示: 此工具类的封装、相关客户端、服务端证书的生成,可参考我的这篇博客:
     *      <linked>https://blog.csdn.net/justry_deng/article/details/91569132</linked>
     *
     *
     * @param isHttps 是否是HTTPS请求
     *
     * @return  HttpClient实例
     * @date 2019/9/18 17:57
     */
    private CloseableHttpClient getHttpClient(boolean isHttps) {
       CloseableHttpClient httpClient;
       if (isHttps) {
          SSLConnectionSocketFactory sslSocketFactory;
          try {
             /// 如果不作证书校验的话
             sslSocketFactory = getSocketFactory(false, null, null);
    
             /// 如果需要证书检验的话
             // 证书
             //InputStream ca = this.getClass().getClassLoader().getResourceAsStream("client/ds.crt");
             // 证书的别名,即:key。 注:cAalias只需要保证唯一即可,不过推荐使用生成keystore时使用的别名。
             // String cAalias = System.currentTimeMillis() + "" + new SecureRandom().nextInt(1000);
             //sslSocketFactory = getSocketFactory(true, ca, cAalias);
          } catch (Exception e) {
             throw new RuntimeException(e);
          }
          httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory).build();
          return httpClient;
       }
       httpClient = HttpClientBuilder.create().build();
       return httpClient;
    }
    
    /**
     * HTTPS辅助方法, 为HTTPS请求 创建SSLSocketFactory实例、TrustManager实例
     *
     * @param needVerifyCa
     *         是否需要检验CA证书(即:是否需要检验服务器的身份)
     * @param caInputStream
     *         CA证书。(若不需要检验证书,那么此处传null即可)
     * @param cAalias
     *         别名。(若不需要检验证书,那么此处传null即可)
     *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
     *
     * @return SSLConnectionSocketFactory实例
     * @throws NoSuchAlgorithmException
     *         异常信息
     * @throws CertificateException
     *         异常信息
     * @throws KeyStoreException
     *         异常信息
     * @throws IOException
     *         异常信息
     * @throws KeyManagementException
     *         异常信息
     * @date 2019/6/11 19:52
     */
    private static SSLConnectionSocketFactory getSocketFactory(boolean needVerifyCa, InputStream caInputStream, String cAalias)
          throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
          IOException, KeyManagementException {
       X509TrustManager x509TrustManager;
       // https请求,需要校验证书
       if (needVerifyCa) {
          KeyStore keyStore = getKeyStore(caInputStream, cAalias);
          TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
          trustManagerFactory.init(keyStore);
          TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
          if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
             throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
          }
          x509TrustManager = (X509TrustManager) trustManagers[0];
          // 这里传TLS或SSL其实都可以的
          SSLContext sslContext = SSLContext.getInstance("TLS");
          sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
          return new SSLConnectionSocketFactory(sslContext);
       }
       // https请求,不作证书校验
       x509TrustManager = new X509TrustManager() {
          @Override
          public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
          }
    
          @Override
          public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
             // 不验证
          }
    
          @Override
          public X509Certificate[] getAcceptedIssuers() {
             return new X509Certificate[0];
          }
       };
       SSLContext sslContext = SSLContext.getInstance("TLS");
       sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
       return new SSLConnectionSocketFactory(sslContext);
    }
    
    /**
     * 获取(密钥及证书)仓库
     * 注:该仓库用于存放 密钥以及证书
     *
     * @param caInputStream
     *         CA证书(此证书应由要访问的服务端提供)
     * @param cAalias
     *         别名
     *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
     * @return 密钥、证书 仓库
     * @throws KeyStoreException 异常信息
     * @throws CertificateException 异常信息
     * @throws IOException 异常信息
     * @throws NoSuchAlgorithmException 异常信息
     * @date 2019/6/11 18:48
     */
    private static KeyStore getKeyStore(InputStream caInputStream, String cAalias)
          throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
       // 证书工厂
       CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
       // 秘钥仓库
       KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
       keyStore.load(null);
       keyStore.setCertificateEntry(cAalias, certificateFactory.generateCertificate(caInputStream));
       return keyStore;
    }

    application/x-www-form-urlencoded表单请求(示例)

    发送文件(示例)

    准备工作:

           如果想要灵活方便的传输文件的话,除了引入org.apache.httpcomponents基本的httpclient依赖外再额外引入org.apache.httpcomponents的httpmime依赖。
    P.S.:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。

    在pom.xml中额外引入:

    <!--
         如果需要灵活的传输文件,引入此依赖后会更加方便
    -->
    <dependency>
    	<groupId>org.apache.httpcomponents</groupId>
    	<artifactId>httpmime</artifactId>
    	<version>4.5.5</version>
    </dependency>

    发送端是这样的:

    /**
     *
     * 发送文件
     *
     * multipart/form-data传递文件(及相关信息)
     *
     * 注:如果想要灵活方便的传输文件的话,
     *    除了引入org.apache.httpcomponents基本的httpclient依赖外
     *    再额外引入org.apache.httpcomponents的httpmime依赖。
     *    追注:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。
     *
     */
    @Test
    public void test4() {
       CloseableHttpClient httpClient = HttpClientBuilder.create().build();
       HttpPost httpPost = new HttpPost("http://localhost:12345/file");
       CloseableHttpResponse response = null;
       try {
          MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
          // 第一个文件
          String filesKey = "files";
          File file1 = new File("C:\\Users\\JustryDeng\\Desktop\\back.jpg");
          multipartEntityBuilder.addBinaryBody(filesKey, file1);
          // 第二个文件(多个文件的话,使用同一个key就行,后端用数组或集合进行接收即可)
          File file2 = new File("C:\\Users\\JustryDeng\\Desktop\\头像.jpg");
          // 防止服务端收到的文件名乱码。 我们这里可以先将文件名URLEncode,然后服务端拿到文件名时在URLDecode。就能避免乱码问题。
          // 文件名其实是放在请求头的Content-Disposition里面进行传输的,如其值为form-data; name="files"; filename="头像.jpg"
          multipartEntityBuilder.addBinaryBody(filesKey, file2, ContentType.DEFAULT_BINARY, URLEncoder.encode(file2.getName(), "utf-8"));
          // 其它参数(注:自定义contentType,设置UTF-8是为了防止服务端拿到的参数出现乱码)
          ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));
          multipartEntityBuilder.addTextBody("name", "邓沙利文", contentType);
          multipartEntityBuilder.addTextBody("age", "25", contentType);
    
          HttpEntity httpEntity = multipartEntityBuilder.build();
          httpPost.setEntity(httpEntity);
    
          response = httpClient.execute(httpPost);
          HttpEntity responseEntity = response.getEntity();
          System.out.println("HTTPS响应状态为:" + response.getStatusLine());
          if (responseEntity != null) {
             System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
             // 主动设置编码,来防止响应乱码
             String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
             System.out.println("HTTPS响应内容为:" + responseStr);
          }
       } catch (ParseException | IOException e) {
          e.printStackTrace();
       } finally {
          try {
             // 释放资源
             if (httpClient != null) {
                httpClient.close();
             }
             if (response != null) {
                response.close();
             }
          } catch (IOException e) {
             e.printStackTrace();
          }
       }
    }

    接收端是这样的:

    发送流(示例)

    发送端是这样的:

    /**
     *
     * 发送流
     *
     */
    @Test
    public void test5() {
       CloseableHttpClient httpClient = HttpClientBuilder.create().build();
       HttpPost httpPost = new HttpPost("http://localhost:12345/is?name=邓沙利文");
       CloseableHttpResponse response = null;
       try {
          InputStream is = new ByteArrayInputStream("流啊流~".getBytes());
          InputStreamEntity ise = new InputStreamEntity(is);
          httpPost.setEntity(ise);
    
          response = httpClient.execute(httpPost);
          HttpEntity responseEntity = response.getEntity();
          System.out.println("HTTPS响应状态为:" + response.getStatusLine());
          if (responseEntity != null) {
             System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
             // 主动设置编码,来防止响应乱码
             String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
             System.out.println("HTTPS响应内容为:" + responseStr);
          }
       } catch (ParseException | IOException e) {
          e.printStackTrace();
       } finally {
          try {
             // 释放资源
             if (httpClient != null) {
                httpClient.close();
             }
             if (response != null) {
                response.close();
             }
          } catch (IOException e) {
             e.printStackTrace();
          }
       }
    }

    接收端是这样的:

     


    再次提示:如果想要自己进行测试,可去下面给的项目代码托管链接,将项目clone下来,然后先启动该
                      SpringBoot项目,然后再运行相关test方法,进行测试。

    工具类提示:使用HttpClient时,可以视情况将其写为工具类。如:Github上Star非常多的一个HttpClient
                          的工具类是httpclientutil。本人在这里也推荐使用该工具类,因为该工具类的编写者封装了
                          很多功能在里面,如果不是有什么特殊的需求的话,完全可以不用造轮子,可以直接使用
                          该工具类。使用方式很简单,可详见https://github.com/Arronlong/httpclientutil


     

    ^_^ 如有不当之处,欢迎指正

    ^_^ 代码托管链接
               
       https://github.com/JustryDeng/P.../Abc_HttpClientDemo

    ^_^ 本文已经被收录进《程序员成长笔记(五)》,作者JustryDeng

    展开全文
  • HttpClient用法--这一篇全了解(内含例子)

    万次阅读 多人点赞 2018-09-15 15:48:14
    HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握...

    HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入。

    org.apache.commons.httpclient.HttpClient与org.apache.http.client.HttpClient的区别

    Commons的HttpClient项目现在是生命的尽头,不再被开发,  已被Apache HttpComponents项目HttpClient和HttpCore  模组取代,提供更好的性能和更大的灵活性。  

    一、简介

    HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。

    下载地址: http://hc.apache.org/downloads.cgi

    二、特性

    1. 基于标准、纯净的java语言。实现了Http1.0和Http1.1

    2. 以可扩展的面向对象的结构实现了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。

    3. 支持HTTPS协议。

    4. 通过Http代理建立透明的连接。

    5. 利用CONNECT方法通过Http代理建立隧道的https连接。

    6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos认证方案。

    7. 插件式的自定义认证方案。

    8. 便携可靠的套接字工厂使它更容易的使用第三方解决方案。

    9. 连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。

    10. 自动处理Set-Cookie中的Cookie。

    11. 插件式的自定义Cookie策略。

    12. Request的输出流可以避免流中内容直接缓冲到socket服务器。

    13. Response的输入流可以有效的从socket服务器直接读取相应内容。

    14. 在http1.0和http1.1中利用KeepAlive保持持久连接。

    15. 直接获取服务器发送的response code和 headers。

    16. 设置连接超时的能力。

    17. 实验性的支持http1.1 response caching。

    18. 源代码基于Apache License 可免费获取。

    三、使用方法

    使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。

    1. 创建HttpClient对象。

    2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

    3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。

    4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。

    5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

    6. 释放连接。无论执行方法是否成功,都必须释放连接

    相关jar包

    commons-cli-1.2.jar  
    commons-codec-1.9.jar  
    commons-logging-1.2.jar  
    fluent-hc-4.5.1.jar  
    httpclient-4.5.1.jar  
    httpclient-cache-4.5.1.jar  
    httpclient-win-4.5.1.jar  
    httpcore-4.4.3.jar  
    httpcore-ab-4.4.3.jar  
    httpcore-nio-4.4.3.jar  
    httpmime-4.5.1.jar  
    jna-4.1.0.jar  
    jna-platform-4.1.0.jar  

    最简单post请求, 源自 http://my.oschina.net/xinxingegeya/blog/282683

    package a;  
       
    import java.io.FileInputStream;  
    import java.io.IOException;  
    import java.util.ArrayList;  
    import java.util.List;  
    import java.util.Properties;  
       
    import org.apache.http.HttpEntity;  
    import org.apache.http.HttpResponse;  
    import org.apache.http.NameValuePair;  
    import org.apache.http.client.HttpClient;  
    import org.apache.http.client.config.RequestConfig;  
    import org.apache.http.client.entity.UrlEncodedFormEntity;  
    import org.apache.http.client.methods.HttpPost;  
    import org.apache.http.impl.client.DefaultHttpClient;  
    import org.apache.http.message.BasicNameValuePair;  
    import org.apache.http.util.EntityUtils;  
       
    public class First {  
        public static void main(String[] args) throws Exception{  
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();  
            formparams.add(new BasicNameValuePair("account", ""));  
            formparams.add(new BasicNameValuePair("password", ""));  
            HttpEntity reqEntity = new UrlEncodedFormEntity(formparams, "utf-8");  
        
            RequestConfig requestConfig = RequestConfig.custom()  
            .setConnectTimeout(5000)//一、连接超时:connectionTimeout-->指的是连接一个url的连接等待时间  
                    .setSocketTimeout(5000)// 二、读取数据超时:SocketTimeout-->指的是连接上一个url,获取response的返回等待时间  
                    .setConnectionRequestTimeout(5000)  
                    .build();  
        
            HttpClient client = new DefaultHttpClient();  
            HttpPost post = new HttpPost("http://cnivi.com.cn/login");  
            post.setEntity(reqEntity);  
            post.setConfig(requestConfig);  
            HttpResponse response = client.execute(post);  
        
            if (response.getStatusLine().getStatusCode() == 200) {  
                HttpEntity resEntity = response.getEntity();  
                String message = EntityUtils.toString(resEntity, "utf-8");  
                System.out.println(message);  
            } else {  
                System.out.println("请求失败");  
            }  
        }  
       
    }  

    四、实例

    主文件

    package com.test;  
          
    import java.io.File;  
    import java.io.FileInputStream;  
    import java.io.IOException;  
    import java.io.UnsupportedEncodingException;  
    import java.security.KeyManagementException;  
    import java.security.KeyStore;  
    import java.security.KeyStoreException;  
    import java.security.NoSuchAlgorithmException;  
    import java.security.cert.CertificateException;  
    import java.util.ArrayList;  
    import java.util.List;  
    import javax.net.ssl.SSLContext;  
    import org.apache.http.HttpEntity;  
    import org.apache.http.NameValuePair;  
    import org.apache.http.ParseException;  
    import org.apache.http.client.ClientProtocolException;  
    import org.apache.http.client.entity.UrlEncodedFormEntity;  
    import org.apache.http.client.methods.CloseableHttpResponse;  
    import org.apache.http.client.methods.HttpGet;  
    import org.apache.http.client.methods.HttpPost;  
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
    import org.apache.http.conn.ssl.SSLContexts;  
    import org.apache.http.conn.ssl.TrustSelfSignedStrategy;  
    import org.apache.http.entity.ContentType;  
    import org.apache.http.entity.mime.MultipartEntityBuilder;  
    import org.apache.http.entity.mime.content.FileBody;  
    import org.apache.http.entity.mime.content.StringBody;  
    import org.apache.http.impl.client.CloseableHttpClient;  
    import org.apache.http.impl.client.HttpClients;  
    import org.apache.http.message.BasicNameValuePair;  
    import org.apache.http.util.EntityUtils;  
    import org.apache.http.client.config.RequestConfig;  
    import org.junit.Test;  
    public class HttpClientTest {  
      //方法见下........  
    }  

    HttpClientUtils工具类

    package com.bobo.code.web.controller.technology.httpcomponents;  
       
       
    import org.apache.http.HttpEntity;  
    import org.apache.http.HttpHost;  
    import org.apache.http.HttpResponse;  
    import org.apache.http.NameValuePair;  
    import org.apache.http.client.HttpClient;  
    import org.apache.http.client.config.RequestConfig;  
    import org.apache.http.client.methods.HttpUriRequest;  
    import org.apache.http.client.methods.RequestBuilder;  
    import org.apache.http.conn.routing.HttpRoute;  
    import org.apache.http.impl.client.CloseableHttpClient;  
    import org.apache.http.impl.client.HttpClientBuilder;  
    import org.apache.http.impl.client.HttpClients;  
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;  
    import org.apache.http.message.BasicNameValuePair;  
    import org.apache.http.util.EntityUtils;  
        
    import java.io.IOException;  
    import java.util.*;  
        
    public class HttpClientUtils {  
        
        private static PoolingHttpClientConnectionManager connectionManager = null;  
        private static HttpClientBuilder httpBuilder = null;  
        private static RequestConfig requestConfig = null;  
        
        private static int MAXCONNECTION = 10;  
        
        private static int DEFAULTMAXCONNECTION = 5;  
        
        private static String IP = "cnivi.com.cn";  
        private static int PORT = 80;  
        
        static {  
            //设置http的状态参数  
            requestConfig = RequestConfig.custom()  
                    .setSocketTimeout(5000)  
                    .setConnectTimeout(5000)  
                    .setConnectionRequestTimeout(5000)  
                    .build();  
        
            HttpHost target = new HttpHost(IP, PORT);  
            connectionManager = new PoolingHttpClientConnectionManager();  
            connectionManager.setMaxTotal(MAXCONNECTION);//客户端总并行链接最大数  
            connectionManager.setDefaultMaxPerRoute(DEFAULTMAXCONNECTION);//每个主机的最大并行链接数  
            connectionManager.setMaxPerRoute(new HttpRoute(target), 20);  
            httpBuilder = HttpClients.custom();  
            httpBuilder.setConnectionManager(connectionManager);  
        }  
        
        public static CloseableHttpClient getConnection() {  
            CloseableHttpClient httpClient = httpBuilder.build();  
            return httpClient;  
        }  
        
        
        public static HttpUriRequest getRequestMethod(Map<String, String> map, String url, String method) {  
            List<NameValuePair> params = new ArrayList<NameValuePair>();  
            Set<Map.Entry<String, String>> entrySet = map.entrySet();  
            for (Map.Entry<String, String> e : entrySet) {  
                String name = e.getKey();  
                String value = e.getValue();  
                NameValuePair pair = new BasicNameValuePair(name, value);  
                params.add(pair);  
            }  
            HttpUriRequest reqMethod = null;  
            if ("post".equals(method)) {  
                reqMethod = RequestBuilder.post().setUri(url)  
                        .addParameters(params.toArray(new BasicNameValuePair[params.size()]))  
                        .setConfig(requestConfig).build();  
            } else if ("get".equals(method)) {  
                reqMethod = RequestBuilder.get().setUri(url)  
                        .addParameters(params.toArray(new BasicNameValuePair[params.size()]))  
                        .setConfig(requestConfig).build();  
            }  
            return reqMethod;  
        }  
        
        public static void main(String args[]) throws IOException {  
            Map<String, String> map = new HashMap<String, String>();  
            map.put("account", "");  
            map.put("password", "");  
        
            HttpClient client = getConnection();  
            HttpUriRequest post = getRequestMethod(map, "http://cnivi.com.cn/login", "post");  
            HttpResponse response = client.execute(post);  
        
            if (response.getStatusLine().getStatusCode() == 200) {  
                HttpEntity entity = response.getEntity();  
                String message = EntityUtils.toString(entity, "utf-8");  
                System.out.println(message);  
            } else {  
                System.out.println("请求失败");  
            }  
        }  
    }  

    get方式

    /** 
         * 发送 get请求 
         */   
        public void get() {   
            CloseableHttpClient httpclient = HttpClients.createDefault();   
            try {   
                // 创建httpget.     
                HttpGet httpget = new HttpGet("http://www.baidu.com/");   
                System.out.println("executing request " + httpget.getURI());   
                // 执行get请求.     
                CloseableHttpResponse response = httpclient.execute(httpget);   
                try {   
                    // 获取响应实体     
                    HttpEntity entity = response.getEntity();   
                    System.out.println("--------------------------------------");   
                    // 打印响应状态     
                    System.out.println(response.getStatusLine());   
                    if (entity != null) {   
                        // 打印响应内容长度     
                        System.out.println("Response content length: " + entity.getContentLength());   
                        // 打印响应内容     
                        System.out.println("Response content: " + EntityUtils.toString(entity));   
                    }   
                    System.out.println("------------------------------------");   
                } finally {   
                    response.close();   
                }   
            } catch (ClientProtocolException e) {   
                e.printStackTrace();   
            } catch (ParseException e) {   
                e.printStackTrace();   
            } catch (IOException e) {   
                e.printStackTrace();   
            } finally {   
                // 关闭连接,释放资源     
                try {   
                    httpclient.close();   
                } catch (IOException e) {   
                    e.printStackTrace();   
                }   
            }   
        }  

    post方式 

    /** 
         * 发送 post请求访问本地应用并根据传递参数不同返回不同结果 
         */   
        public void post() {   
            // 创建默认的httpClient实例.     
            CloseableHttpClient httpclient = HttpClients.createDefault();   
            // 创建httppost     
            HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");   
            // 创建参数队列     
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();   
            formparams.add(new BasicNameValuePair("type", "house"));   
            UrlEncodedFormEntity uefEntity;   
            try {   
                uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   
                httppost.setEntity(uefEntity);   
                System.out.println("executing request " + httppost.getURI());   
                CloseableHttpResponse response = httpclient.execute(httppost);   
                try {   
                    HttpEntity entity = response.getEntity();   
                    if (entity != null) {   
                        System.out.println("--------------------------------------");   
                        System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));   
                        System.out.println("--------------------------------------");   
                    }   
                } finally {   
                    response.close();   
                }   
            } catch (ClientProtocolException e) {   
                e.printStackTrace();   
            } catch (UnsupportedEncodingException e1) {   
                e1.printStackTrace();   
            } catch (IOException e) {   
                e.printStackTrace();   
            } finally {   
                // 关闭连接,释放资源     
                try {   
                    httpclient.close();   
                } catch (IOException e) {   
                    e.printStackTrace();   
                }   
            }   
        }  

    post方式乱码补充 

    如果有乱码,可以偿试使用 StringEntity 来替换HttpEntity:

    StringEntity content =new StringEntity(soapRequestData.toString(), Charset.forName("UTF-8"));// 第二个参数,设置后才会对,内容进行编码  
            content.setContentType("application/soap+xml; charset=UTF-8");  
            content.setContentEncoding("UTF-8");  
            httppost.setEntity(content);  

    具体SOAP协议代码如下:

        package com.isoftstone.core.service.impl;  
          
        import java.io.BufferedReader;  
        import java.io.File;  
        import java.io.FileInputStream;  
        import java.io.FileReader;  
        import java.io.IOException;  
        import java.io.InputStreamReader;  
        import java.nio.charset.Charset;  
        import java.util.Scanner;  
          
        import org.apache.http.HttpEntity;  
        import org.apache.http.HttpResponse;  
        import org.apache.http.client.ClientProtocolException;  
        import org.apache.http.client.HttpClient;  
        import org.apache.http.client.entity.EntityBuilder;  
        import org.apache.http.client.methods.HttpPost;  
        import org.apache.http.entity.ContentType;  
        import org.apache.http.entity.StringEntity;  
        import org.apache.http.impl.client.HttpClients;  
        import org.apache.http.util.EntityUtils;  
        import org.apache.log4j.Logger;  
        import org.jdom.Document;  
        import org.jdom.Element;  
          
        import com.isoftstone.core.common.constant.RequestConstants;  
        import com.isoftstone.core.common.tools.XmlTool;  
        import com.isoftstone.core.service.intf.ServiceOfStringPara;  
        /** 
         * 
         * 
         */  
        public class DeloittePricingSingleCarImpl implements ServiceOfStringPara {  
            private  String serviceUrl = "http://10.30.0.35:7001/ZSInsUW/Auto/PricingService";  
          
            private static Logger log = Logger.getLogger(DeloittePricingSingleCarImpl.class.getName());  
          
            public String invoke(String sRequest) {  
                  
                StringBuffer soapRequestData = new StringBuffer();  
                soapRequestData.append("<soapenv:Envelope");  
                soapRequestData.append("  xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" ");  
                soapRequestData.append("  xmlns:prov=\"http://provider.webservice.zsins.dtt.com/\">");  
                soapRequestData.append(" <soapenv:Header/> ");  
                soapRequestData.append("<soapenv:Body>");  
                soapRequestData.append("<prov:executePrvPricing>");  
                soapRequestData.append("<arg0>");  
                soapRequestData.append("<![CDATA[" + sRequest + "]]>");  
                soapRequestData.append("</arg0>");  
                soapRequestData.append("</prov:executePrvPricing>");  
                soapRequestData.append(" </soapenv:Body>");  
                soapRequestData.append("</soapenv:Envelope>");  
          
                HttpClient httpclient = HttpClients.createDefault();  
                HttpPost httppost = new HttpPost(serviceUrl);  
          
                StringEntity content =new StringEntity(soapRequestData.toString(), Charset.forName("UTF-8"));// 第二个参数,设置后才会对,内容进行编码  
                content.setContentType("application/soap+xml; charset=UTF-8");  
                content.setContentEncoding("UTF-8");  
                httppost.setEntity(content);  
                  
                //用下面的服务器端以UTF-8接收到的报文会乱码,原因未知  
        //        HttpEntity reqEntity = EntityBuilder.create().setContentType(  
        //                ContentType.TEXT_PLAIN) // .TEXT_PLAIN  
        //                .setText(soapRequestData.toString()).build();  
        //        httppost.setEntity(reqEntity);  
        //        httppost.addHeader("Content-Type",  
        //                "application/soap+xml; charset=utf-8");  
                HttpResponse response = null;  
                Document doc = null;  
                String returnXml = null;  
                String sentity = null;  
                try {  
                    response = httpclient.execute(httppost);  
                    HttpEntity resEntity = response.getEntity();  
                    if (resEntity != null) {  
                        sentity = EntityUtils.toString(resEntity, "UTF-8");  
                        doc = XmlTool.getDocument(sentity, RequestConstants.ENCODE);  
                        System.out.println(doc.toString());  
                        Element eRoot = doc.getRootElement();  
                        Element body = eRoot.getChild("Body", eRoot.getNamespace());  
                        Element resp = (Element) body.getChildren().get(0);  
                        Element returnele = resp.getChild("return");  
                        returnXml = returnele.getText().toString();  
                    }  
                } catch (ClientProtocolException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                } catch (Exception e) {  
                    e.printStackTrace();  
                } finally {  
                    log.info("发送给系统的请求报文:\n" + soapRequestData.toString());  
                    log.info("系统返回的响应报文:\n" + sentity);  
                    log.info("返回给核心的的报文:\n" + returnXml);  
                }  
                return returnXml;  
            }  
              
              
            public String getServiceUrl() {  
                return serviceUrl;  
            }  
          
          
            public void setServiceUrl(String serviceUrl) {  
                this.serviceUrl = serviceUrl;  
            }  
          
          
            public static void main(String[] args) throws Exception{  
                File file = new File("D:/test.txt");  
                System.out.println(file.exists());  
                  
                String temp2 = null;  
                StringBuilder sb2 = new StringBuilder();  
                InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"GBK");  
                BufferedReader br = new BufferedReader(isr);  
                temp2 = br.readLine();  
                  
                while( temp2 != null ){  
                    sb2.append(temp2);  
                    temp2 = br.readLine();  
                }  
                String sss = sb2.toString();  
        //        System.out.println(sss.toString());  
                new DeloittePricingSingleCarImpl().invoke(sss);  
            }  
        }  
    
    

     

    post提交表单

    /** 
         * post方式提交表单(模拟用户登录请求) 
         */   
        public void postForm() {   
            // 创建默认的httpClient实例.     
            CloseableHttpClient httpclient = HttpClients.createDefault();   
            // 创建httppost     
            HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");   
            // 创建参数队列     
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();   
            formparams.add(new BasicNameValuePair("username", "admin"));   
            formparams.add(new BasicNameValuePair("password", "123456"));   
            UrlEncodedFormEntity uefEntity;   
            try {   
                uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   
                httppost.setEntity(uefEntity);   
                System.out.println("executing request " + httppost.getURI());   
                CloseableHttpResponse response = httpclient.execute(httppost);   
                try {   
                    HttpEntity entity = response.getEntity();   
                    if (entity != null) {   
                        System.out.println("--------------------------------------");   
                        System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));   
                        System.out.println("--------------------------------------");   
                    }   
                } finally {   
                    response.close();   
                }   
            } catch (ClientProtocolException e) {   
                e.printStackTrace();   
            } catch (UnsupportedEncodingException e1) {   
                e1.printStackTrace();   
            } catch (IOException e) {   
                e.printStackTrace();   
            } finally {   
                // 关闭连接,释放资源     
                try {   
                    httpclient.close();   
                } catch (IOException e) {   
                    e.printStackTrace();   
                }   
            }   
        }  

    文件上传

    /** 
         * 上传文件 
         */   
        public void upload() {   
            CloseableHttpClient httpclient = HttpClients.createDefault();   
            try {   
                HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceFile.action");   
         
                FileBody bin = new FileBody(new File("F:\\image\\sendpix0.jpg"));   
                StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);   
         
                HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("bin", bin).addPart("comment", comment).build();   
         
                httppost.setEntity(reqEntity);   
         
                System.out.println("executing request " + httppost.getRequestLine());   
                CloseableHttpResponse response = httpclient.execute(httppost);   
                try {   
                    System.out.println("----------------------------------------");   
                    System.out.println(response.getStatusLine());   
                    HttpEntity resEntity = response.getEntity();   
                    if (resEntity != null) {   
                        System.out.println("Response content length: " + resEntity.getContentLength());   
                    }   
                    EntityUtils.consume(resEntity);   
                } finally {   
                    response.close();   
                }   
            } catch (ClientProtocolException e) {   
                e.printStackTrace();   
            } catch (IOException e) {   
                e.printStackTrace();   
            } finally {   
                try {   
                    httpclient.close();   
                } catch (IOException e) {   
                    e.printStackTrace();   
                }   
            }   
        } 

    ssl连接

    /** 
         * HttpClient连接SSL 
         */   
        public void ssl() {   
            CloseableHttpClient httpclient = null;   
            try {   
                KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());   
                FileInputStream instream = new FileInputStream(new File("d:\\tomcat.keystore"));   
                try {   
                    // 加载keyStore d:\\tomcat.keystore     
                    trustStore.load(instream, "123456".toCharArray());   
                } catch (CertificateException e) {   
                    e.printStackTrace();   
                } finally {   
                    try {   
                        instream.close();   
                    } catch (Exception ignore) {   
                    }   
                }   
                // 相信自己的CA和所有自签名的证书   
                SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();   
                // 只允许使用TLSv1协议   
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,   
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);   
                httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();   
                // 创建http请求(get方式)   
                HttpGet httpget = new HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action");   
                System.out.println("executing request" + httpget.getRequestLine());   
                CloseableHttpResponse response = httpclient.execute(httpget);   
                try {   
                    HttpEntity entity = response.getEntity();   
                    System.out.println("----------------------------------------");   
                    System.out.println(response.getStatusLine());   
                    if (entity != null) {   
                        System.out.println("Response content length: " + entity.getContentLength());   
                        System.out.println(EntityUtils.toString(entity));   
                        EntityUtils.consume(entity);   
                    }   
                } finally {   
                    response.close();   
                }   
            } catch (ParseException e) {   
                e.printStackTrace();   
            } catch (IOException e) {   
                e.printStackTrace();   
            } catch (KeyManagementException e) {   
                e.printStackTrace();   
            } catch (NoSuchAlgorithmException e) {   
                e.printStackTrace();   
            } catch (KeyStoreException e) {   
                e.printStackTrace();   
            } finally {   
                if (httpclient != null) {   
                    try {   
                        httpclient.close();   
                    } catch (IOException e) {   
                        e.printStackTrace();   
                    }   
                }   
            }   
        }   

    关于RequestConfig的配置:  

    源自:  

    http://segmentfault.com/a/1190000000587944

    http://blog.csdn.net/walkerjong/article/details/51710945

    public void requestConfig(){  
    //      新建一个RequestConfig:  
            RequestConfig defaultRequestConfig = RequestConfig.custom()  
                //一、连接目标服务器超时时间:ConnectionTimeout-->指的是连接一个url的连接等待时间  
                .setConnectTimeout(5000)  
                //二、读取目标服务器数据超时时间:SocketTimeout-->指的是连接上一个url,获取response的返回等待时间  
                .setSocketTimeout(5000)  
                //三、从连接池获取连接的超时时间:ConnectionRequestTimeout  
                .setConnectionRequestTimeout(5000)  
                .build();  
               
    //      这个超时可以设置为客户端级别,作为所有请求的默认值:  
            CloseableHttpClient httpclient = HttpClients.custom()  
                .setDefaultRequestConfig(defaultRequestConfig)  
                .build();  
    //       httpclient.execute(httppost);的时候可以让httppost直接享受到httpclient中的默认配置.  
               
    //      Request不会继承客户端级别的请求配置,所以在自定义Request的时候,需要将客户端的默认配置拷贝过去:  
            HttpGet httpget = new HttpGet("http://www.apache.org/");  
            RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)  
                .setProxy(new HttpHost("myotherproxy", 8080))  
                .build();  
            httpget.setConfig(requestConfig);  
    //      httpget可以单独地使用新copy的requestConfig请求配置,不会对别的request请求产生影响  
        }  

    httpGet或httpPost 的abort()和releaseConnection()差异

    //httpPost.abort();//中断请求,接下来可以开始另一段请求,所以个人理应,用这个应该可以在session中虚拟登录  
     //httpPost.releaseConnection();//释放请求.如果释放了相当于要清空session  

    可知模拟登录可以如下:  源自 http://bbs.csdn.net/topics/390195343

    package com.bms.core;  
         
    import java.io.IOException;  
    import java.util.ArrayList;  
    import java.util.List;  
         
    import org.apache.http.Consts;  
    import org.apache.http.HttpEntity;  
    import org.apache.http.HttpResponse;  
    import org.apache.http.NameValuePair;  
    import org.apache.http.client.ClientProtocolException;  
    import org.apache.http.client.entity.UrlEncodedFormEntity;  
    import org.apache.http.client.methods.HttpGet;  
    import org.apache.http.client.methods.HttpPost;  
    import org.apache.http.impl.client.DefaultHttpClient;  
    import org.apache.http.message.BasicNameValuePair;  
    import org.apache.http.util.EntityUtils;  
         
    import com.bms.util.CommonUtil;  
         
    public class Test2 {  
         
        /** 
         * @param args 
         * @throws IOException 
         * @throws ClientProtocolException 
         */  
        public static void main(String[] args) throws ClientProtocolException, IOException {  
            DefaultHttpClient httpclient = new DefaultHttpClient();  
         
             HttpGet httpGet = new HttpGet("http://www.baidu.com");  
             String body = "";  
             HttpResponse response;  
             HttpEntity entity;  
             response = httpclient.execute(httpGet);  
             entity = response.getEntity();  
             body = EntityUtils.toString(entity);//这个就是页面源码了  
             httpGet.abort();//中断请求,接下来可以开始另一段请求  
             System.out.println(body);  
             //httpGet.releaseConnection();//释放请求.如果释放了相当于要清空session  
             //以下是post方法  
             HttpPost httpPost = new HttpPost("http://www.baidu.com");//一定要改成可以提交的地址,这里用百度代替  
             List <NameValuePair> nvps = new ArrayList <NameValuePair>();  
             nvps.add(new BasicNameValuePair("name", "1"));//名值对  
             nvps.add(new BasicNameValuePair("account", "xxxx"));  
             httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));  
             response = httpclient.execute(httpPost);  
             entity = response.getEntity();  
             body = EntityUtils.toString(entity);  
             System.out.println("Login form get: " + response.getStatusLine());//这个可以打印状态  
             httpPost.abort();  
             System.out.println(body);  
             httpPost.releaseConnection();  
        }  
         
    }  

    源自  http://blog.csdn.net/wangpeng047/article/details/19624529#reply

    其它相关资料: 非CloseableHttpClient  HTTPClient模块的HttpGet和HttpPost

    HttpClient 4.3教程

    httpclient异常情况分析

    我项目中用到的HttpClientUtil (2016/12/17)

    package com.isoftstone.pcis.isc.util;  
      
    import java.io.IOException;  
    import java.io.InterruptedIOException;  
    import java.net.UnknownHostException;  
      
    import javax.net.ssl.SSLException;  
    import javax.net.ssl.SSLHandshakeException;  
      
    import org.apache.http.HttpEntityEnclosingRequest;  
    import org.apache.http.HttpRequest;  
    import org.apache.http.NoHttpResponseException;  
    import org.apache.http.client.HttpRequestRetryHandler;  
    import org.apache.http.client.protocol.HttpClientContext;  
    import org.apache.http.config.Registry;  
    import org.apache.http.config.RegistryBuilder;  
    import org.apache.http.conn.ConnectTimeoutException;  
    import org.apache.http.conn.socket.ConnectionSocketFactory;  
    import org.apache.http.conn.socket.LayeredConnectionSocketFactory;  
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;  
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
    import org.apache.http.impl.client.CloseableHttpClient;  
    import org.apache.http.impl.client.HttpClients;  
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;  
    import org.apache.http.protocol.HttpContext;  
    import com.isoftstone.pcis.isc.util.ProperUtil;  
      
    public class HttpClientUtil {  
          
        private static CloseableHttpClient httpclient = null;   
          
        static final int maxTotal=Integer.valueOf(ProperUtil.get("maxTotal")).intValue();//总最大连接数  
        static final int defaultMaxPerRoute=Integer.valueOf(ProperUtil.get("corePoolSize")).intValue();//每条线路最大连接数 = 本系统核心线程数 , 这样永远不会超过最大连接  
          
         public static CloseableHttpClient getHttpClient() {  
                  
                if (null == httpclient) {  
                    synchronized (HttpClientUtil.class) {  
                        if (null == httpclient) {  
                            httpclient = getNewHttpClient();  
                        }  
                    }  
                }  
                  
                return httpclient;  
            }  
           
           private static CloseableHttpClient getNewHttpClient() {  
      
                
                // 设置连接池  
                ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();  
                LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();  
                Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", plainsf).register("https", sslsf).build();  
                PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);  
                // 配置最大连接数  
                cm.setMaxTotal(maxTotal);  
                // 配置每条线路的最大连接数  
                cm.setDefaultMaxPerRoute(defaultMaxPerRoute);  
                  
                // 请求重试处理  
                HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {  
                    @Override  
                    public boolean retryRequest(IOException exception,  
                            int executionCount, HttpContext context) {  
                        if (executionCount >= 2) {// 如果已经重试了2次,就放弃  
                            return false;  
                        }  
                        if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试  
                            return true;  
                        }  
                        if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常  
                            return false;  
                        }  
                        if (exception instanceof InterruptedIOException) {// 超时  
                            return false;  
                        }  
                        if (exception instanceof UnknownHostException) {// 目标服务器不可达  
                            return false;  
                        }  
                        if (exception instanceof ConnectTimeoutException) {// 连接被拒绝  
                            return false;  
                        }  
                        if (exception instanceof SSLException) {// SSL握手异常  
                            return false;  
                        }  
      
                        HttpClientContext clientContext = HttpClientContext.adapt(context);  
                        HttpRequest request = clientContext.getRequest();  
                          
                        if (!(request instanceof HttpEntityEnclosingRequest)) {  
                            return true;  
                        }  
                        return false;  
                    }  
      
                };  
                  
                CloseableHttpClient newHttpclient=null;  
              
                    newHttpclient = HttpClients.custom()  
                                               .setConnectionManager(cm)  
    //                                           .setDefaultRequestConfig(requestConfig)  
                                               .setRetryHandler(httpRequestRetryHandler)  
                                               .build();  
                      
                 return newHttpclient;  
           }  
    }  

    我自己整理的HttpClientTool

    package com.isoftstone.core.util;  
      
    import java.io.IOException;  
    import java.io.InterruptedIOException;  
    import java.net.UnknownHostException;  
      
    import javax.net.ssl.SSLException;  
    import javax.net.ssl.SSLHandshakeException;  
      
    import org.apache.http.HttpEntityEnclosingRequest;  
    import org.apache.http.HttpHost;  
    import org.apache.http.HttpRequest;  
    import org.apache.http.NoHttpResponseException;  
    import org.apache.http.client.HttpRequestRetryHandler;  
    import org.apache.http.client.config.RequestConfig;  
    import org.apache.http.client.protocol.HttpClientContext;  
    import org.apache.http.config.Registry;  
    import org.apache.http.config.RegistryBuilder;  
    import org.apache.http.conn.ConnectTimeoutException;  
    import org.apache.http.conn.routing.HttpRoute;  
    import org.apache.http.conn.socket.ConnectionSocketFactory;  
    import org.apache.http.conn.socket.LayeredConnectionSocketFactory;  
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;  
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
    import org.apache.http.impl.client.CloseableHttpClient;  
    import org.apache.http.impl.client.HttpClients;  
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;  
    import org.apache.http.protocol.HttpContext;  
      
    /** 
     * org.apache.http.impl.client.CloseableHttpClient链接池生成工具 
     * @reference http://www.cnblogs.com/whatlonelytear/articles/4835538.html 
     * @author King 
     * @date 20170601 
     */  
    public class HttpClientTool {  
      
        // org.apache.http.impl.client.CloseableHttpClient  
        private static CloseableHttpClient httpclient = null;  
      
        // 这里就直接默认固定了,因为以下三个参数在新建的method中仍然可以重新配置并被覆盖.  
        static final int connectionRequestTimeout = 5000;// ms毫秒,从池中获取链接超时时间  
        static final int connectTimeout = 5000;// ms毫秒,建立链接超时时间  
        static final int socketTimeout = 30000;// ms毫秒,读取超时时间  
      
        // 总配置,主要涉及是以下两个参数,如果要作调整没有用到properties会比较后麻烦,但鉴于一经粘贴,随处可用的特点,就不再做依赖性配置化处理了.  
        // 而且这个参数同一家公司基本不会变动.  
        static final int maxTotal = 500;// 最大总并发,很重要的参数  
        static final int maxPerRoute = 100;// 每路并发,很重要的参数  
      
        // 正常情况这里应该配成MAP或LIST  
        // 细化配置参数,用来对每路参数做精细化处理,可以管控各ip的流量,比如默认配置请求baidu:80端口最大100个并发链接,  
        static final String detailHostName = "http://www.baidu.com";// 每个细化配置之ip(不重要,在特殊场景很有用)  
        static final int detailPort = 80;// 每个细化配置之port(不重要,在特殊场景很有用)  
        static final int detailMaxPerRoute = 100;// 每个细化配置之最大并发数(不重要,在特殊场景很有用)  
      
        public static CloseableHttpClient getHttpClient() {  
            if (null == httpclient) {  
                synchronized (HttpClientTool.class) {  
                    if (null == httpclient) {  
                        httpclient = init();  
                    }  
                }  
            }  
            return httpclient;  
        }  
      
        /** 
         * 链接池初始化 这里最重要的一点理解就是. 让CloseableHttpClient 一直活在池的世界里, 但是HttpPost却一直用完就消掉. 
         * 这样可以让链接一直保持着. 
         *  
         * @return 
         */  
        private static CloseableHttpClient init() {  
            CloseableHttpClient newHttpclient = null;  
      
            // 设置连接池  
            ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();  
            LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();  
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", plainsf).register("https", sslsf).build();  
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);  
            // 将最大连接数增加  
            cm.setMaxTotal(maxTotal);  
            // 将每个路由基础的连接增加  
            cm.setDefaultMaxPerRoute(maxPerRoute);  
      
            // 细化配置开始,其实这里用Map或List的for循环来配置每个链接,在特殊场景很有用.  
            // 将每个路由基础的连接做特殊化配置,一般用不着  
            HttpHost httpHost = new HttpHost(detailHostName, detailPort);  
            // 将目标主机的最大连接数增加  
            cm.setMaxPerRoute(new HttpRoute(httpHost), detailMaxPerRoute);  
            // cm.setMaxPerRoute(new HttpRoute(httpHost2),  
            // detailMaxPerRoute2);//可以有细化配置2  
            // cm.setMaxPerRoute(new HttpRoute(httpHost3),  
            // detailMaxPerRoute3);//可以有细化配置3  
            // 细化配置结束  
      
            // 请求重试处理  
            HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {  
                @Override  
                public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {  
                    if (executionCount >= 2) {// 如果已经重试了2次,就放弃  
                        return false;  
                    }  
                    if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试  
                        return true;  
                    }  
                    if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常  
                        return false;  
                    }  
                    if (exception instanceof InterruptedIOException) {// 超时  
                        return false;  
                    }  
                    if (exception instanceof UnknownHostException) {// 目标服务器不可达  
                        return false;  
                    }  
                    if (exception instanceof ConnectTimeoutException) {// 连接被拒绝  
                        return false;  
                    }  
                    if (exception instanceof SSLException) {// SSL握手异常  
                        return false;  
                    }  
      
                    HttpClientContext clientContext = HttpClientContext.adapt(context);  
                    HttpRequest request = clientContext.getRequest();  
                    // 如果请求是幂等的,就再次尝试  
                    if (!(request instanceof HttpEntityEnclosingRequest)) {  
                        return true;  
                    }  
                    return false;  
                }  
            };  
      
            // 配置请求的超时设置  
            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectionRequestTimeout).setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();  
            newHttpclient = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).setRetryHandler(httpRequestRetryHandler).build();  
            return newHttpclient;  
        }  
    } 
    package com.alqsoft.utils;
    
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.ArrayList;
    import java.util.List;
    
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.ParseException;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.config.CookieSpecs;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.cookie.Cookie;
    import org.apache.http.cookie.CookieOrigin;
    import org.apache.http.cookie.CookieSpec;
    import org.apache.http.cookie.CookieSpecProvider;
    import org.apache.http.cookie.MalformedCookieException;
    import org.apache.http.impl.client.BasicCookieStore;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.cookie.BestMatchSpecFactory;
    import org.apache.http.impl.cookie.BrowserCompatSpec;
    import org.apache.http.impl.cookie.BrowserCompatSpecFactory;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.protocol.HttpContext;
    import org.apache.http.util.EntityUtils;
    
    
    public class HttpClientObject {
        private static Log logger = LogFactory.getLog(HttpClientObject.class);
        private CloseableHttpClient httpClient = null;
        private HttpResponse response;
    
        private HttpPost httpPost = null;
    
        private HttpGet httpGet = null;
    
        private String paramKey = "";
    
        private String paramValue = "";
    
        private String responseString;
    
        public void setParamKey(String paramKey) {
            this.paramKey = paramKey;
        }
    
        public void setParamValue(String paramValue) {
            this.paramValue = paramValue;
        }
    
        public String getResponseString() {
            return responseString;
        }
    
        public HttpClientObject() {
            this.getHttpClient();
        }
    
        private List<NameValuePair> getRequestBody() {
            NameValuePair pair1 = new BasicNameValuePair(paramKey, paramValue);
            List<NameValuePair> pairList = new ArrayList<NameValuePair>();
            pairList.add(pair1);
            return pairList;
        }
    
    
        public void submit() {
            try {
                if (httpPost != null) {
                    response = httpClient.execute(httpPost);
                    httpPost = null;
                }
                if (httpGet != null) {
                    response = httpClient.execute(httpGet);
                    httpGet = null;
                }
                this.response();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    
        private void response() {
            String result = "";
            BufferedReader in = null;
            try {
                HttpEntity httpEntity = response.getEntity();
                responseString = EntityUtils.toString(httpEntity);
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
    
    
        }
    
    
        public void setPost(String httpUrl) {
            try {
                HttpEntity requestHttpEntity = new UrlEncodedFormEntity(this.getRequestBody());
                httpPost = new HttpPost(httpUrl);
                httpPost.addHeader("Content-Type", "”application/json;charset=UTF-8");
                httpPost.setEntity(requestHttpEntity);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
    
        public void setGet(String httpUrl) {
            httpGet = new HttpGet(httpUrl);
            httpGet.addHeader("Content-Type", "text/html;charset=UTF-8");
        }
    
    
        private void getHttpClient() {
            BasicCookieStore cookieStore = new BasicCookieStore();
            CookieSpecProvider easySpecProvider = new CookieSpecProvider() {
                public CookieSpec create(HttpContext context) {
    
    
                    return new BrowserCompatSpec() {
                        @Override
                        public void validate(Cookie cookie, CookieOrigin origin)
                                throws MalformedCookieException {
    // Oh, I am easy
                        }
                    };
                }
    
    
            };
            Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()
                    .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory())
                    .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory())
                    .register("easy", easySpecProvider).build();
    
    
            RequestConfig requestConfig = RequestConfig.custom().setCookieSpec("easy")
                    .setSocketTimeout(20000).setConnectTimeout(20000).build();
    
    
            httpClient = HttpClients.custom().setDefaultCookieSpecRegistry(r)
                    .setDefaultRequestConfig(requestConfig).setDefaultCookieStore(cookieStore).build();
        }
    
    
        /**
         * httpclient发送http get请求;
         *
         * @return
         * @throws URISyntaxException
         * @throws IOException
         * @throws ClientProtocolException
         */
        public static String sendGet(String uriPath, List<NameValuePair> ns)
                throws URISyntaxException, ClientProtocolException, IOException {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            URIBuilder uri = new URIBuilder();
            uri.setPath(uriPath);
            uri.addParameters(ns);
            URI u = uri.build();
            HttpGet httpget = new HttpGet(u);
            CloseableHttpResponse response = httpclient.execute(httpget);
            return EntityUtils.toString(response.getEntity());
        }
    
    
        /**
         * httpclient发送http post请求;
         *
         * @return
         * @throws URISyntaxException
         * @throws IOException
         * @throws ClientProtocolException
         */
        public static String sendPost(String uriPath, List<NameValuePair> ns)
                throws URISyntaxException, ClientProtocolException, IOException {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            URIBuilder uri = new URIBuilder();
            uri.setPath(uriPath);
            uri.addParameters(ns);
            URI u = uri.build();
            HttpPost httpPost = new HttpPost(u);
            CloseableHttpResponse response = httpclient.execute(httpPost);
            return EntityUtils.toString(response.getEntity());
        }
    
    }
    
    
    使用方法如下:
    
            String signUrl= ”路径“;
    
            try{
            List<NameValuePair> nameValuePairs=new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("phone",phone));
            nameValuePairs.add(new BasicNameValuePair("xytId",String.valueOf(xytId)));
            nameValuePairs.add(new BasicNameValuePair("balance",balance));
    
            String result=HttpClientObject.sendPost(signUrl,nameValuePairs);
            logger.info("result: = "+result);
            JSONObject jsonObject=JSON.parseObject(result);
    
            Integer code=Integer.valueOf(jsonObject.getString("code"));
            if(code.equals(0)){
            code1=0L;
            }else if(code.equals(1)){
            code1=1L;
            }else if(code.equals(3)){
            code1=3L;
            }
            }catch(Exception e){
            e.printStackTrace();
            }

     

     

    展开全文
  • HttpClient入门教程

    万次阅读 2017-12-20 13:45:04
    HttpClient简介 HttpClient 功能介绍  1. 读取网页(HTTP/HTTPS)内容  2、使用POST方式提交数据(httpClient3)   3. 处理页面重定向  4. 模拟登录开心网  5. 提交XML格式参数   6. 访问启用认证的...


     

    HttpClient简介

    HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。更多信息请关注http://hc.apache.org/

     

    HttpClient 功能介绍

    以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。

    • 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)

    • 支持自动转向

    • 支持 HTTPS 协议

    • 支持代理服务器等

    应用HttpClient来对付各种顽固的WEB服务器
    转自:http://blog.csdn.net/ambitiontan/archive/2006/01/06/572171.aspx

    一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等。所访问的这些页面有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需要认证以及是一些通过加密方式传输,例如HTTPS。目前我们使用的浏览器处理这些情况都不会构成问题。不过你可能在某些时候需要通过程序来访问这样的一些页面,比如从别人的网页中“偷”一些数据;利用某些站点提供的页面来完成某种功能,例如说我们想知道某个手机号码的归属地而我们自己又没有这样的数据,因此只好借助其他公司已有的网站来完成这个功能,这个时候我们需要向网页提交手机号码并从返回的页面中解析出我们想要的数据来。如果对方仅仅是一个很简单的页面,那我们的程序会很简单,本文也就没有必要大张旗鼓的在这里浪费口舌。但是考虑到一些服务授权的问题,很多公司提供的页面往往并不是可以通过一个简单的URL就可以访问的,而必须经过注册然后登录后方可使用提供服务的页面,这个时候就涉及到COOKIE问题的处理。我们知道目前流行的动态网页技术例如ASP、JSP无不是通过COOKIE来处理会话信息的。为了使我们的程序能使用别人所提供的服务页面,就要求程序首先登录后再访问服务页面,这过程就需要自行处理cookie,想想当你用java.net.HttpURLConnection来完成这些功能时是多么恐怖的事情啊!况且这仅仅是我们所说的顽固的WEB服务器中的一个很常见的“顽固”!再有如通过HTTP来上传文件呢?不需要头疼,这些问题有了“它”就很容易解决了!

     

    我们不可能列举所有可能的顽固,我们会针对几种最常见的问题进行处理。当然了,正如前面说到的,如果我们自己使用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情,因此在开始之前我们先要介绍一下一个开放源码的项目,这个项目就是Apache开源组织中的httpclient,它隶属于Jakarta的commons项目,目前的版本是2.0RC2。commons下本来已经有一个net的子项目,但是又把httpclient单独提出来,可见http服务器的访问绝非易事。

    Commons-httpclient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。通过它可以让原来很头疼的事情现在轻松的解决,例如你不再管是HTTP或者HTTPS的通讯方式,告诉它你想使用HTTPS方式,剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时经常碰到的几个问题进行分别介绍如何使用httpclient来解决它们,为了让读者更快的熟悉这个项目我们最开始先给出一个简单的例子来读取一个网页的内容,然后循序渐进解决掉前进中的所有问题。

     

    1. 读取网页(HTTP/HTTPS)内容

    下面是我们给出的一个简单的例子用来访问某个页面

    复制代码
    /** 
     *最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面
      *@authorLiudong
    */
    public class SimpleClient {
    public static void main(String[] args) throws 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();
       }
    }
    复制代码

     

    在这个例子中首先创建一个HTTP客户端(HttpClient)的实例,然后选择提交的方法是GET或者POST,最后在HttpClient实例上执行提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。其实用一行代码也就可以搞定整个请求的过程,非常的简单!

     

    2、使用POST方式提交数据(httpClient3)

    httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可,下面这里将给出关于两种模拟上传方式的代码

     

    第一种:模拟上传url文件(该方式也适合做普通post请求):

    复制代码
    /**
         * 上传url文件到指定URL
         * @param fileUrl 上传图片url
         * @param postUrl 上传路径及参数,注意有些中文参数需要使用预先编码 eg : URLEncoder.encode(appName, "UTF-8")
         * @return
         * @throws IOException
         */
        public static String doUploadFile(String postUrl) throws IOException {
            if(StringUtils.isEmpty(postUrl))
                return null;
            String response = "";
            PostMethod postMethod = new PostMethod(postUrl);
            try {
                HttpClient client = new HttpClient();
                client.getHttpConnectionManager().getParams()
                        .setConnectionTimeout(50000);// 设置连接时间
                int status = client.executeMethod(postMethod);
                if (status == HttpStatus.SC_OK) {
                    InputStream inputStream = postMethod.getResponseBodyAsStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            inputStream));
                    StringBuffer stringBuffer = new StringBuffer();
                    String str = "";
                    while ((str = br.readLine()) != null) {
                        stringBuffer.append(str);
                    }
                    response = stringBuffer.toString();
                } else {
                    response = "fail";
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放连接
                postMethod.releaseConnection();
            }
            return response;
        }
    复制代码

     

     

    第二种:模拟文件上传到指定位置

     

    复制代码
    /**
         * 上传文件到指定URL
         * @param file
         * @param url
         * @return
         * @throws IOException
         */
        public static String doUploadFile(File file, String url) throws IOException {
            String response = "";
            if (!file.exists()) {
                return "file not exists";
            }
            PostMethod postMethod = new PostMethod(url);
            try {
                //----------------------------------------------
                // FilePart:用来上传文件的类,file即要上传的文件
                FilePart fp = new FilePart("file", file);
                Part[] parts = { fp };
    
                // 对于MIME类型的请求,httpclient建议全用MulitPartRequestEntity进行包装
                MultipartRequestEntity mre = new MultipartRequestEntity(parts,
                        postMethod.getParams());
                postMethod.setRequestEntity(mre);
                //---------------------------------------------
                HttpClient client = new HttpClient();
                client.getHttpConnectionManager().getParams()
                        .setConnectionTimeout(50000);// 由于要上传的文件可能比较大 , 因此在此设置最大的连接超时时间
                int status = client.executeMethod(postMethod);
                if (status == HttpStatus.SC_OK) {
                    InputStream inputStream = postMethod.getResponseBodyAsStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            inputStream));
                    StringBuffer stringBuffer = new StringBuffer();
                    String str = "";
                    while ((str = br.readLine()) != null) {
                        stringBuffer.append(str);
                    }
                    response = stringBuffer.toString();
                } else {
                    response = "fail";
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放连接
                postMethod.releaseConnection();
            }
            return response;
        }
    复制代码

     

     

    3. 处理页面重定向

    在JSP/Servlet编程中response.sendRedirect方法就是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward …>的区别在于后者是在服务器中实现页面的跳转,也就是说应用容器加载了所要跳转的页面的内容并返回给客户端;而前者是返回一个状态码,这些状态码的可能值见下表,然后客户端读取需要跳转到的页面的URL并重新加载新的页面。就是这样一个过程,所以我们编程的时候就要通过HttpMethod.getStatusCode()方法判断返回值是否为下表中的某个值来判断是否需要跳转。如果已经确认需要进行页面跳转了,那么可以通过读取HTTP头中的location属性来获取新的地址。

     


    下面的代码片段演示如何处理页面的重定向

    复制代码
    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){
          Stringnewuri=header.getValue();
          if((newuri==null)||(newuri.equals("")))
             newuri="/";
             GetMethodredirect=newGetMethod(newuri);
             client.executeMethod(redirect);
             System.out.println("Redirect:"+redirect.getStatusLine().toString());
             redirect.releaseConnection();
       }else 
        System.out.println("Invalid redirect");
    }
    复制代码

     

     

    我们可以自行编写两个JSP页面,其中一个页面用response.sendRedirect方法重定向到另外一个页面用来测试上面的例子。

     

    4. 模拟登录开心网

    本小节应该说是HTTP客户端编程中最常碰见的问题,很多网站的内容都只是对注册用户可见的,这种情况下就必须要求使用正确的用户名和口令登录成功后,方可浏览到想要的页面。因为HTTP协议是无状态的,也就是连接的有效期只限于当前请求,请求内容结束后连接就关闭了。在这种情况下为了保存用户的登录信息必须使用到Cookie机制。以JSP/Servlet为例,当浏览器请求一个JSP或者是Servlet的页面时,应用服务器会返回一个参数,名为jsessionid(因不同应用服务器而异),值是一个较长的唯一字符串的Cookie,这个字符串值也就是当前访问该站点的会话标识。浏览器在每访问该站点的其他页面时候都要带上jsessionid这样的Cookie信息,应用服务器根据读取这个会话标识来获取对应的会话信息。

    对于需要用户登录的网站,一般在用户登录成功后会将用户资料保存在服务器的会话中,这样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息,然后就可以判断用户资料是否存在于会话信息中,如果存在则允许访问页面,否则跳转到登录页面中要求用户输入帐号和口令进行登录。这就是一般使用JSP开发网站在处理用户登录的比较通用的方法。

    这样一来,对于HTTP的客户端来讲,如果要访问一个受保护的页面时就必须模拟浏览器所做的工作,首先就是请求登录页面,然后读取Cookie值;再次请求登录页面并加入登录页所需的每个参数;最后就是请求最终所需的页面。当然在除第一次请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前请求是否已经通过验证。说了这么多,可是如果你使用httpclient的话,你甚至连一行代码都无需增加,你只需要先传递登录信息执行登录过程,然后直接访问想要的页面,跟访问一个普通的页面没有任何区别,因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实现了模拟登陆开心网并向自己好友发送消息的功能。

     

    复制代码
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    import org.apache.commons.httpclient.Cookie;
    import org.apache.commons.httpclient.Header;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpStatus;
    import org.apache.commons.httpclient.NameValuePair;
    import org.apache.commons.httpclient.cookie.CookiePolicy;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.methods.PostMethod;
    import org.apache.commons.httpclient.params.HttpClientParams;
    import org.apache.commons.httpclient.params.HttpMethodParams;
    
    class Login {
        public static String loginurl = "https://security.kaixin001.com/login/login_post.php";
        static Cookie[] cookies = {};
    
        static HttpClient httpClient = new HttpClient();
        
        static String email = "xxx@qq.com";//你的email
        static String psw = "xxx";//你的密码
        // 消息发送的action
        String url = "http://www.kaixin001.com/home/";
    
        public static void getUrlContent()
                throws Exception {
    
            HttpClientParams httparams = new HttpClientParams();
            httparams.setSoTimeout(30000);
            httpClient.setParams(httparams);
    
            httpClient.getHostConfiguration().setHost("www.kaixin001.com", 80);
    
            httpClient.getParams().setParameter(
                    HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
    
            PostMethod login = new PostMethod(loginurl);
            login.addRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=UTF-8");
    
            NameValuePair Email = new NameValuePair("loginemail", email);// 邮箱
            NameValuePair password = new NameValuePair("password", psw);// 密码
            // NameValuePair code = new NameValuePair( "code"
            // ,"????");//有时候需要验证码,暂时未解决
    
            NameValuePair[] data = { Email, password };
            login.setRequestBody(data);
    
            httpClient.executeMethod(login);
            int statuscode = login.getStatusCode();
            System.out.println(statuscode + "-----------");
            String result = login.getResponseBodyAsString();
            System.out.println(result+"++++++++++++");
    
            cookies = httpClient.getState().getCookies();
            System.out.println("==========Cookies============");
            int i = 0;
            for (Cookie c : cookies) {
                System.out.println(++i + ":   " + c);
            }
            httpClient.getState().addCookies(cookies);
    
            // 当state为301或者302说明登陆页面跳转了,登陆成功了
            if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY)
                    || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY)
                    || (statuscode == HttpStatus.SC_SEE_OTHER)
                    || (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
                // 读取新的 URL 地址
                Header header = login.getResponseHeader("location");
                // 释放连接
                login.releaseConnection();
                System.out.println("获取到跳转header>>>" + header);
                if (header != null) {
                    String newuri = header.getValue();
                    if ((newuri == null) || (newuri.equals("")))
                        newuri = "/";
                    GetMethod redirect = new GetMethod(newuri);
                    // 
                    redirect.setRequestHeader("Cookie", cookies.toString());
                    httpClient.executeMethod(redirect);
                    System.out.println("Redirect:"
                            + redirect.getStatusLine().toString());
                    redirect.releaseConnection();
    
                } else
                    System.out.println("Invalid redirect");
            } else {
                // 用户名和密码没有被提交,当登陆多次后需要验证码的时候会出现这种未提交情况
                System.out.println("用户没登陆");
                System.exit(1);
            }
    
        }
    
        public static void sendMsg() throws Exception {
            // 登录后发消息
            System.out.println("*************发消息***********");
    
            String posturl = "http://www.kaixin001.com/msg/post.php";
            PostMethod poster = new PostMethod(posturl);
    
            poster.addRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=UTF-8");
            poster.setRequestHeader("Cookie", cookies.toString());
    
            NameValuePair uids = new NameValuePair("uids", "89600585");// 发送的好友对象的id,此处换成你的好友id
            NameValuePair content = new NameValuePair("content", "你好啊!");// 需要发送的信息的内容
            NameValuePair liteeditor_0 = new NameValuePair("liteeditor_0", "你好啊!");// 需要发送的信息的内容
            NameValuePair texttype = new NameValuePair("texttype", "plain");
            NameValuePair send_separate = new NameValuePair("send_separate", "0");
            NameValuePair service = new NameValuePair("service", "0");
            NameValuePair[] msg = { uids, content, texttype, send_separate, service,liteeditor_0 };
    
            poster.setRequestBody(msg);
            httpClient.executeMethod(poster);
    
            String result = poster.getResponseBodyAsString();
            System.out.println(result+"++++++++++++");
            //System.out.println(StreamOut(result, "iso8859-1"));
            int statuscode = poster.getStatusCode();
            System.out.println(statuscode + "-----------");
            if(statuscode == 301 || statuscode == 302){
                // 读取新的 URL 地址
                Header header = poster.getResponseHeader("location");
                System.out.println("获取到跳转header>>>" + header);
                if (header != null) {
                    String newuri = header.getValue();
                    if ((newuri == null) || (newuri.equals("")))
                        newuri = "/";
                    GetMethod redirect = new GetMethod(newuri);
                    // 
                    redirect.setRequestHeader("Cookie", cookies.toString());
                    httpClient.executeMethod(redirect);
                    System.out.println("Redirect:"
                            + redirect.getStatusLine().toString());
                    redirect.releaseConnection();
    
                } else
                    System.out.println("Invalid redirect");
            }
            
                poster.releaseConnection();
        }
    
        public static String StreamOut(InputStream txtis, String code)
                throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(txtis,
                    code));
            String tempbf;
            StringBuffer html = new StringBuffer(100);
            while ((tempbf = br.readLine()) != null) {
                html.append(tempbf + "\n");
            }
            return html.toString();
    
        }
    }
    复制代码

     

     

    5. 提交XML格式参数

    提交XML格式的参数很简单,仅仅是一个提交时候的ContentType问题,下面的例子演示从文件文件中读取XML信息并提交给服务器的过程,该过程可以用来测试Web服务。

    复制代码
    import java.io.File; 
    import java.io.FileInputStream; 
    import org.apache.commons.httpclient.HttpClient; 
    import org.apache.commons.httpclient.methods.EntityEnclosingMethod; 
    import org.apache.commons.httpclient.methods.PostMethod;
    /** 
     *用来演示提交XML格式数据的例子
    */
    public class PostXMLClient {
    
       public static void main(String[] args) throws Exception {
          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(); 
       } 
    }
    复制代码

     

     

    6. 访问启用认证的页面

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

    下面例子是从httpclient的CVS服务器中下载的,它简单演示如何访问一个认证保护的页面:

    复制代码
    import org.apache.commons.httpclient.HttpClient; 
    import org.apache.commons.httpclient.UsernamePasswordCredentials; 
    import org.apache.commons.httpclient.methods.GetMethod; 
    
    public class BasicAuthenticationExample { 
    
       public BasicAuthenticationExample() { 
       }
    
       public static void main(String[] args) throws Exception {
          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+ "\n" + get.getResponseBodyAsString());
          get.releaseConnection();
       } 
    }
    复制代码

     

     

    7. 多线程模式下使用

    多线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问,为了保证多线程工作环境下不产生冲突,httpclient使用了一个多线程连接管理器的类:MultiThreadedHttpConnectionManager,要使用这个类很简单,只需要在构造HttpClient实例的时候传入即可,代码如下:

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

    HttpClient client = new HttpClient(connectionManager);

    以后尽管访问client实例即可。

     

    httpClient完整封装

    HttpInvoke.java:封装了HttpClient调度的必要参数设置,以及post,get等常用方法

    复制代码
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.commons.httpclient.*;
    import org.apache.commons.httpclient.auth.AuthScope;
    import org.apache.commons.httpclient.methods.PostMethod;
    import org.apache.commons.httpclient.methods.GetMethod;
    
    import java.util.Iterator;
    import java.util.Map;
    import java.net.SocketTimeoutException;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class HttpInvoker {
        private Log logger = LogFactory.getLog(HttpInvoker.class);
        private static HttpInvoker httpInvoker = new HttpInvoker();
        private HttpClient client = null;
        private String charset = "gbk";
        private int timeout = 10000;
        private boolean useProxy = false;
        private String proxyHost = null;
        private int proxyPort;
        private String proxyUsername = null;
        private String proxyPassword = null;
        private boolean initialized = false;
        
        public static HttpInvoker getInstance() {
            return httpInvoker;
        }
    
        private HttpInvoker() {
            client = new HttpClient(new MultiThreadedHttpConnectionManager());
            client.getParams().setParameter("http.protocol.content-charset", "gbk");
            client.getParams().setContentCharset("gbk");
            client.getParams().setSoTimeout(timeout);
        }
    
        public HttpInvoker(String charset, int timeout, boolean useProxy,
                           String proxyHost, int proxyPort, String proxyUsername,
                           String proxyPassword) {
            client = new HttpClient(new MultiThreadedHttpConnectionManager());
            if(charset != null && !charset.trim().equals("")) {
                this.charset = charset;
            }
            if(timeout > 0) {
                this.timeout = timeout;
            }
            client.getParams().setParameter("http.protocol.content-charset", charset);
            client.getParams().setContentCharset(charset);
            client.getParams().setSoTimeout(timeout);
            if(useProxy && proxyHost != null &&
                    !proxyHost.trim().equals("") && proxyPort > 0) {
                HostConfiguration hc = new HostConfiguration();
                hc.setProxy(proxyHost, proxyPort);
                client.setHostConfiguration(hc);
                if (proxyUsername != null && !proxyUsername.trim().equals("") &&
                        proxyPassword != null && !proxyPassword.trim().equals("")) {
                    client.getState().setProxyCredentials(AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUsername, proxyPassword));
                }
            }
            initialized = true;
            logger.debug("HttpInvoker初始化完成");
        }
    
        public synchronized void init() {
            if(charset != null && !charset.trim().equals("")) {
                client.getParams().setParameter("http.protocol.content-charset", charset);
                client.getParams().setContentCharset(charset);
            }
            if(timeout > 0) {
                client.getParams().setSoTimeout(timeout);
            }
            if(useProxy && proxyHost != null &&
                    !proxyHost.trim().equals("") && proxyPort > 0) {
                HostConfiguration hc = new HostConfiguration();
                hc.setProxy(proxyHost, proxyPort);
                client.setHostConfiguration(hc);
                if (proxyUsername != null && !proxyUsername.trim().equals("") &&
                        proxyPassword != null && !proxyPassword.trim().equals("")) {
                    client.getState().setProxyCredentials(AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUsername, proxyPassword));
                }
            }
            initialized = true;
            logger.debug("HttpInvoker初始化完成");
        }
    
        public String invoke(String url) throws Exception {
            return invoke(url, null, false);
        }
    
        public String invoke(String url, Map params, boolean isPost) throws Exception {
            logger.debug("HTTP调用[" + (isPost?"POST":"GET") + "][" + url + "][" + params + "]");
            HttpMethod httpMethod = null;
            String result = "";
            try {
                if(isPost && params != null && params.size() > 0) {
                    Iterator paramKeys = params.keySet().iterator();
                    httpMethod = new PostMethod(url);
                    NameValuePair[] form = new NameValuePair[params.size()];
                    int formIndex = 0;
                    while(paramKeys.hasNext()) {
                        String key = (String)paramKeys.next();
                        Object value = params.get(key);
                        if(value != null && value instanceof String && !value.equals("")) {
                            form[formIndex] = new NameValuePair(key, (String)value);
                            formIndex++;
                        } else if(value != null && value instanceof String[] &&
                                ((String[])value).length > 0) {
                            NameValuePair[] tempForm =
                                    new NameValuePair[form.length + ((String[])value).length - 1];
                            for(int i=0; i<formIndex; i++) {
                                tempForm[i] = form[i];
                            }
                            form = tempForm;
                            for(String v : (String[])value) {
                                form[formIndex] = new NameValuePair(key, (String)v);
                                formIndex++;
                            }
                        }
                    }
                    ((PostMethod)httpMethod).setRequestBody(form);
                } else {
                    if(params != null && params.size() > 0) {
                        Iterator paramKeys = params.keySet().iterator();
                        StringBuffer getUrl = new StringBuffer(url.trim());
                        if(url.trim().indexOf("?") > -1) {
                            if(url.trim().indexOf("?") < url.trim().length()-1 &&
                                    url.trim().indexOf("&")  < url.trim().length()-1) {
                                getUrl.append("&");
                            }
                        } else {
                            getUrl.append("?");
                        }
                        while(paramKeys.hasNext()) {
                            String key = (String)paramKeys.next();
                            Object value = params.get(key);
                            if(value != null && value instanceof String && !value.equals("")) {
                                getUrl.append(key).append("=").append(value).append("&");
                            } else if(value != null && value instanceof String[] &&
                                    ((String[])value).length > 0) {
                                for(String v : (String[])value) {
                                    getUrl.append(key).append("=").append(v).append("&");
                                }
                            }
                        }
                        if(getUrl.lastIndexOf("&") == getUrl.length()-1) {
                            httpMethod = new GetMethod(getUrl.substring(0, getUrl.length()-1));
                        } else {
                            httpMethod = new GetMethod(getUrl.toString());
                        }
                    } else {
                        httpMethod = new GetMethod(url);
                    }
                }
                client.executeMethod(httpMethod);
    //            result = httpMethod.getResponseBodyAsString();
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        httpMethod.getResponseBodyAsStream(),"ISO-8859-1"));
                String line = null;
                String html = null;
                while((line = reader.readLine()) != null){
                    if(html == null) {
                        html = "";
                    } else {
                        html += "\r\n";
                    }
                    html += line;
                }
                if(html != null) {
                    result = new String(html.getBytes("ISO-8859-1"), charset);
                }
            } catch (SocketTimeoutException e) {
                logger.error("连接超时[" + url + "]");
                throw e;
            } catch (java.net.ConnectException e) {
                logger.error("连接失败[" + url + "]");
                throw e;
            } catch (Exception e) {
                logger.error("连接时出现异常[" + url + "]");
                throw e;
            } finally {
                if (httpMethod != null) {
                    try {
                        httpMethod.releaseConnection();
                    } catch (Exception e) {
                        logger.error("释放网络连接失败[" + url + "]");
                        throw e;
                    }
                }
            }
    
            return result;
        }
    
        public void setCharset(String charset) {
            this.charset = charset;
        }
    
        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }
    
        public void setProxyHost(String proxyHost) {
            this.proxyHost = proxyHost;
        }
    
        public void setProxyPort(int proxyPort) {
            this.proxyPort = proxyPort;
        }
    
        public void setProxyUsername(String proxyUsername) {
            this.proxyUsername = proxyUsername;
        }
    
        public void setProxyPassword(String proxyPassword) {
            this.proxyPassword = proxyPassword;
        }
    
        public void setUseProxy(boolean useProxy) {
            this.useProxy = useProxy;
        }
    
        public synchronized boolean isInitialized() {
            return initialized;
        }
    }
    复制代码

     

    http访问网络的代理ip和端口,还有使用用户及密码都可以在Spring容器中注入进来:

    复制代码
    <bean id="httpInvoker" class="HttpInvoker">
            <constructor-arg type="java.lang.String" value="gbk" /><!--useProxy-->
            <constructor-arg type="int" value="10000" /><!--useProxy-->
            <constructor-arg type="boolean" value="true" /><!--useProxy-->
            <!--代理地址 -->
            <constructor-arg type="java.lang.String" value="192.168.1.1" />
            <constructor-arg type="int" value="8080" />
            <constructor-arg type="java.lang.String" value="" /><!--用户名-->
            <constructor-arg type="java.lang.String" value="" /><!--密码-->
    </bean>
    复制代码

     

     

    使用方式:post

    Map<String,String> params = new HashMap<String,String>();
    params.put("check", check);
    String result = httpInvoker.invoke( "someURL", params, true);

    使用方式:get

    String content  = httpInvoker.invoke(url);

     

    参考资料:

    httpclient首页:    http://jakarta.apache.org/commons/httpclient/
    关于NTLM是如何工作:  http://davenport.sourceforge.net/ntlm.html


    --------------------------------------------

    HttpClient入门
    http://blog.csdn.net/ambitiontan/archive/2006/01/07/572644.aspx

    Jakarta Commons HttpClient 学习笔记
    http://blog.csdn.net/cxl34/archive/2005/01/19/259051.aspx

    Cookies,SSL,httpclient的多线程处理,HTTP方法
    http://blog.csdn.net/bjbs_270/archive/2004/11/05/168233.aspx

     

    原文地址:https://www.cnblogs.com/ITtangtang/p/3968093.html


    展开全文
  • HttpClient使用详解

    万次阅读 多人点赞 2014-02-28 11:04:29
    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端...HttpClient是Apache Jakarta Common下的子项目,用来提供高效的
  • 关于httpclient 连接失效引发的问题

    千次阅读 2016-12-25 21:55:57
    关于httpclient 连接失效引发的问题
  • 案发现场 昨天晚上突然短信收到 APM (即 Application Performance Management 的简称,我们内部自己搭建了这样一套系统来对应用的性能、可靠性进行线上的监控和预警的一种机制)大量告警 画外音: 监控是一种非常...
  • CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(connectionManager) .setMaxConnTotal(400) .setMaxConnPerRoute(150) .evictExpiredConnections() .build(); ...
  • 案发现场 昨天晚上突然短信收到 APM (即 Application Performance Management 的简称,我们内部自己搭建了这样一套系统来对应用的性能、可靠性进行线上的监控和预警的一种机制)大量告警 画外音: 监控是一种非常...
  • 情景 后端部署了新的代码,在几分钟后似乎所有的爬取相关的服务均不可用。一服务频繁报错提示:「连接超时: 当前过于拥挤」。 获取连接池状态 首先立即打开日志查看错误消息,显示:Timeout waiting for connection ...
  • HttpClient介绍

    2020-06-09 15:57:13
    本文内容整理自: ...HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅...因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入。 org.apache.commons
  • HttpClient 请求 URL字符集转码问题

    万次阅读 2019-07-18 18:03:54
    问题是这样的,我用eclipse发送httpclient请求如下没有问题,但是在idea中就返回400,为毛呢???excuse me? package com.vol.timingTasks; import org.apache.http.HttpEntity; import org.apache....
  • HttpClient

    万次阅读 2019-03-30 23:25:46
    HttpClient 入门
  • HttpClient

    千次阅读 2005-03-17 09:38:00
    1、HttpClient的功能基于标准,纯正java,实现了http1.0和1.1。在一个可扩展的OO框架内,实现了HTTP的全部方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)支持HTTPS(ssl上的HTTP)的加密操作透明地...
  • Java工具类--通过HttpClient发送http请求

    万次阅读 多人点赞 2015-11-27 15:17:34
    在写网络程序的时候,经常会有从网址获取数据的需求,上一篇解析JSON就需要从百度...HttpClient的介绍 The most essential function of HttpClient is to execute HTTP methods. Execution of an HTTP method involves
  • HttpClient

    千次阅读 2018-03-26 23:13:32
    HttpClient简介HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。官方站点:...
  • httpclient

    千次阅读 2013-12-29 21:22:44
    HttpClient 是 Apache Jakarta Common 下的子项目,...本文首先介绍 HTTPClient,然后根据作者实际工作经验给出了一些常见问题的解决方法。  HttpClient 基本功能的使用  (一)、GET 方法  使用 HttpClient 需要
  • HttpClient

    千次阅读 2014-04-09 08:27:43
    HttpClient 是我最近想研究的东西,以前想过的一些应用没能有很好的实现,发现这个开源项目之后就有点眉目了,令人头痛的cookie问题还是有办法解决滴。在网上整理了一些东西,写得很好,寄放在这里。HTTP 协议可能是...
  • httpclient-4.5所需jar包

    万次下载 热门讨论 2015-07-15 15:43:21
    httpclient-4.5所需jar包,里面包含httpclient-4.5.jar等等10个必须的开发包
  • httpclient

    千次阅读 2010-03-18 23:32:00
    package test;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import org.apache.commons.httpclient.Header;import org.apache.commons.httpclient.HttpClient;import org.apache.c

空空如也

1 2 3 4 5 ... 20
收藏数 117,923
精华内容 47,169
关键字:

httpclient