HttpClient研究学习总结

本文深入探讨了HttpClient的功能与使用,作为ApacheJakartaCommons项目的一部分,HttpClient提供了高效、现代且功能丰富的HTTP客户端工具包,支持HTTP协议的最新标准,适合各种HTTP感知的客户端应用开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HttpClient研究学习总结

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

一、Http简介

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

      HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。 

尽管java.net包提供了通过HTTP访问资源的基本功能,但它并不能提供许多应用程序所需的全部灵活性或功能。 
HttpClient试图通过提供一个高效的,最新的,功能丰富的包来实现最新的HTTP标准和建议的客户端来填补这个空白。

为扩展而设计,同时为基本的HTTP协议提供强大的支持,任何构建HTTP感知的客户端应用程序(例如Web浏览器,Web服务客户端或利用或扩展HTTP协议进行分布式通信的系统)的HttpClient都可能是有用的。

HTTP协议的主要特点可概括如下: 
1.支持客户/服务器模式。 
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。 
由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。 
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。 
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。 
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

二、使用方法

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

首先需要导入HttpClientjar包,具体可以到官网下载,下载地址: http://hc.apache.org/downloads.cgi

commons-codec-1.7.jar,commons-logging-1.1.1.jar,httpclient-4.2.2.jar,httpcore-4.2.2.jar

1. 创建HttpClient对象,最新版的httpClient使用实现类的是closeableHTTPClient,以前的default作废了。

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

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

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

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

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

三、使用实例

代码如下(注:程序采用的httpclient和httpcore依赖包的版本为4.2.5):

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import java.util.UUID;
import net.sf.json.JSONObject;
import java.nio.charset.Charset;

public static boolean httpPostWithJson(JSONObject jsonObj,String url,String appId){
    boolean isSuccess = false;
    
    HttpPost post = null;
    try {
        HttpClient httpClient = new DefaultHttpClient();

        // 设置超时时间
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000);
            
        post = new HttpPost(url);
        // 构造消息头
        post.setHeader("Content-type", "application/json; charset=utf-8");
        post.setHeader("Connection", "Close");
        String sessionId = getSessionId();
        post.setHeader("SessionId", sessionId);
        post.setHeader("appid", appid);
                    
        // 构建消息实体
        StringEntity entity = new StringEntity(jsonObj.toString(), Charset.forName("UTF-8"));
        entity.setContentEncoding("UTF-8");
        // 发送Json格式的数据请求
        entity.setContentType("application/json");
        post.setEntity(entity);
            
        HttpResponse response = httpClient.execute(post);
            
        // 检验返回码
        int statusCode = response.getStatusLine().getStatusCode();
        if(statusCode != HttpStatus.SC_OK){
            LogUtil.info("请求出错: "+statusCode);
            isSuccess = false;
        }else{
            int retCode = 0;
            String sessendId = "";
            // 返回码中包含retCode及会话Id
            for(Header header : response.getAllHeaders()){
                if(header.getName().equals("retcode")){
                    retCode = Integer.parseInt(header.getValue());
                }
                if(header.getName().equals("SessionId")){
                    sessendId = header.getValue();
                }
            }
            
            if(ErrorCodeHelper.IAS_SUCCESS != retCode ){
                // 日志打印
                LogUtil.info("error return code,  sessionId: "sessendId"\t"+"retCode: "+retCode);
                isSuccess = false;
            }else{
                isSuccess = true;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        isSuccess = false;
    }finally{
        if(post != null){
            try {
                post.releaseConnection();
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    return isSuccess;
}

// 构建唯一会话Id
public static String getSessionId(){
    UUID uuid = UUID.randomUUID();
    String str = uuid.toString();
    return str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24);
}
 1    package  test;
 2    import  java.io.IOException;
 3    import  org.apache.commons.httpclient. * ;
 4    import  org.apache.commons.httpclient.methods.GetMethod;
 5    import  org.apache.commons.httpclient.params.HttpMethodParams;
 6    public   class  GetSample{
 7       public   static   void  main(String[] args) {
 8          // 构造HttpClient的实例 
 9          HttpClient httpClient  =   new  HttpClient();
10          // 创建GET方法的实例 
11          GetMethod getMethod  =   new  GetMethod( " http://www.ibm.com " );
12          // 使用系统提供的默认的恢复策略 
13          getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
14                                                   new  DefaultHttpMethodRetryHandler());
15          try  {
16            // 执行getMethod 
17            int  statusCode  =  httpClient.executeMethod(getMethod);
18            if  (statusCode  !=  HttpStatus.SC_OK) {
19                System.err.println( " Method failed:  " 
20                                         +  getMethod.getStatusLine());
21            }
22             // 读取内容 
23             byte [] responseBody  =  getMethod.getResponseBody();
24             // 处理内容 
25             System.out.println( new  String(responseBody));
26          }  catch  (HttpException e) {
27             // 发生致命的异常,可能是协议不对或者返回的内容有问题 
28             System.out.println( " Please check your provided http address! " );
29             e.printStackTrace();
30          }  catch  (IOException e) {
31             // 发生网络异常 
32             e.printStackTrace();
33          }  finally  {
34             // 释放连接 
35             getMethod.releaseConnection();
36          }
37        }
38     }
 1   String url  =   " http://www.test.com/login.jsp " ;
 2   PostMethod postMethod  =   new  PostMethod(url);
 3   //  填入各个表单域的值 
 4   NameValuePair[] data  =  {  new  NameValuePair( " id " ,  " youUserName " ),                
 5                            new  NameValuePair( " passwd " ,  " yourPwd " ) };
 6   //  将表单的值放入postMethod中 
 7   postMethod.setRequestBody(data);
 8   //  执行postMethod 
 9   int  statusCode  =  httpClient.executeMethod(postMethod);
10   //  HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
11   //  301或者302 
12   if  (statusCode  ==  HttpStatus.SC_MOVED_PERMANENTLY  || 
13                        statusCode  ==  HttpStatus.SC_MOVED_TEMPORARILY) {
14       //  从头中取出转向的地址 
15       Header locationHeader  =  postMethod.getResponseHeader( " location " );
16       String location  =   null ;
17       if  (locationHeader  !=   null ) {
18          location  =  locationHeader.getValue();
19          System.out.println( " The page was redirected to: "   +  location);
20       }  else  {
21          System.err.println( " Location field value is null. " );
22       }
23       return ;
24   } 

public void testPost() {  
        // 创建默认的httpClient实例.    
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        // 创建httppost    
        HttpPost httppost = new HttpPost("http://localhost:8080/");  
        // 创建参数队列    
        List<NameValuePair> list = new ArrayList<NameValuePair>();  
        list.add(new BasicNameValuePair("admin", "我心自在"));  
        UrlEncodedFormEntity uefEntity;  
        try {  
            uefEntity = new UrlEncodedFormEntity(list, "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();  
            }  
        }  
    }  
import java.io.File;
import java.net.URI;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
 * 带参数的GET请求
 * 两种方式:
 *       1.直接将参数拼接到url后面 如:?wd=java
 *       2.使用URI的方法设置参数 setParameter("wd", "java")
 */
public class DoGETParam {
    public static void main(String[] args) throws Exception {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 定义请求的参数
        URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build();
        // 创建http GET请求
        HttpGet httpGet = new HttpGet(uri);
        //response 对象
        CloseableHttpResponse response = null;
        try {
            // 执行http get请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                //内容写入文件
                FileUtils.writeStringToFile(new File("E:\\devtest\\baidu-param.html"), content, "UTF-8");
                System.out.println("内容长度:"+content.length());
            }
        } finally {
            if (response != null) {
                response.close();
            }
            httpclient.close();
        }
    }
}
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
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;

/**
 * 带有参数的Post请求
 * NameValuePair
 */
public class DoPOSTParam {
    public static void main(String[] args) throws Exception {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建http POST请求
        HttpPost httpPost = new HttpPost("http://www.oschina.net/search");
        // 设置2个post参数,一个是scope、一个是q
        List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
        parameters.add(new BasicNameValuePair("scope", "project"));
        parameters.add(new BasicNameValuePair("q", "java"));
        // 构造一个form表单式的实体
        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
        // 将请求实体设置到httpPost对象中
        httpPost.setEntity(formEntity);
        //伪装浏览器
        httpPost.setHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
        CloseableHttpResponse response = null;
        try {
            // 执行请求
            response = httpclient.execute(httpPost);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                //内容写入文件
                FileUtils.writeStringToFile(new File("E:\\devtest\\oschina-param.html"), content, "UTF-8");
                System.out.println("内容长度:"+content.length());
            }
        } finally {
            if (response != null) {
                response.close();
            }
            httpclient.close();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值