HttpURLConnection与HttpClient

一.HttpURLConnection

1.基本介绍

一个支持HTTP特定功能的URLConnection。

HttpURLConnection是Java的标准类,它继承自URLConnection,可用于向指定网站发送GET请求、POST请求。

使用这个类遵循以下模式:

1.通过调用URL.openConnection()来获得一个新的HttpURLConnection对象,并且将其结果强制转换为HttpURLConnection.

2.准备请求。一个请求主要的参数是它的URI。请求头可能也包含元数据,例如证书,首选数据类型和会话cookies.

3.可以选择性的上传一个请求体。HttpURLConnection实例必须设置setDoOutput(true),如果它包含一个请求体。通过将数据写入一个由getOutStream()返回的输出流来传输数据。

4.读取响应。响应头通常包含元数据例如响应体的内容类型和长度,修改日期和会话cookies。响应体可以被由getInputStream返回的输入流读取。如果响应没有响应体,则该方法会返回一个空的流。

5.关闭连接。一旦一个响应体已经被阅读后,HttpURLConnection 对象应该通过调用disconnect()关闭。断开连接会释放被一个connection占有的资源,这样它们就能被关闭或再次使用。

2.提供的几个方法

int getResponseCode(); // 获取服务器的响应代码。
String getResponseMessage(); // 获取服务器的响应消息。
String getResponseMethod(); // 获取发送请求的方法。
void setRequestMethod(String method); // 设置发送请求的方法。

3.使用例子

3.1使用GET方式访问HTTP

GET请求示例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


public class GetDemo {

public static void main(String[] args) {
    try {
        // 1. 得到访问地址的URL
        URL url = new URL(
                "http://localhost:8080/Servlet/do_login.do?username=test&password=123456");
        // 2. 得到网络访问对象java.net.HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        /* 3. 设置请求参数(过期时间,输入、输出流、访问方式),以流的形式进行连接 */
        // 设置是否向HttpURLConnection输出
        connection.setDoOutput(false);
        // 设置是否从httpUrlConnection读入
        connection.setDoInput(true);
        // 设置请求方式
        connection.setRequestMethod("GET");
        // 设置是否使用缓存
        connection.setUseCaches(true);
        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
        connection.setInstanceFollowRedirects(true);
        // 设置超时时间
        connection.setConnectTimeout(3000);
        // 连接
        connection.connect();
        // 4. 得到响应状态码的返回值 responseCode
        int code = connection.getResponseCode();
        // 5. 如果返回值正常,数据在网络中是以流的形式得到服务端返回的数据
        String msg = "";
        if (code == 200) { // 正常响应
            // 从流中读取响应信息
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
            String line = null;

            while ((line = reader.readLine()) != null) { // 循环从流中读取
                msg += line + "\n";
            }
            reader.close(); // 关闭流
        }
        // 6. 断开连接,释放资源
        connection.disconnect();

        // 显示响应结果
        System.out.println(msg);
    } catch (IOException e) {
        e.printStackTrace();
    		}
	 }
}

3.2使用POST方式访问HTTP

POST请求示例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class PostDemo {

public static void main(String[] args) {
    try {
        // 1. 获取访问地址URL
        URL url = new URL("http://localhost:8080/Servlet/do_login.do");
        // 2. 创建HttpURLConnection对象
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        /* 3. 设置请求参数等 */
        // 请求方式
        connection.setRequestMethod("POST");
        // 超时时间
        connection.setConnectTimeout(3000);
        // 设置是否输出
        connection.setDoOutput(true);
        // 设置是否读入
        connection.setDoInput(true);
        // 设置是否使用缓存
        connection.setUseCaches(false);
        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
        connection.setInstanceFollowRedirects(true);
        // 设置使用标准编码格式编码参数的名-值对
        connection.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        // 连接
        connection.connect();
        /* 4. 处理输入输出 */
        // 写入参数到请求中
        String params = "username=test&password=123456";
        OutputStream out = connection.getOutputStream();
        out.write(params.getBytes());
        out.flush();
        out.close();
        // 从连接中读取响应信息
        String msg = "";
        int code = connection.getResponseCode();
        if (code == 200) {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
            String line;

            while ((line = reader.readLine()) != null) {
                msg += line + "\n";
            }
            reader.close();
        }
        // 5. 断开连接
        connection.disconnect();

        // 处理结果
        System.out.println(msg);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
	  		  }
	 }
}

4.使用总结

①HttpURLConnection对象不能直接构造,需要通过URL类中的openConnection()方法来获得。
②HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的TCP连接,并没有实际发送HTTP请求。HTTP请求 实际上直到我们获取服务器响应数据(如调用getInputStream()、getResponseCode()等方法)时才正式发送出去。
③对HttpURLConnection对象的配置都需要在connect()方法执行之前完成。
④HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。
⑤HTTP正文的内容是通过OutputStream流写入的, 向流中写入的数据不会立即发送到网络,而是存在于内存缓冲区中,待流关闭时,根据写入的内容生成HTTP正文。
⑥调用getInputStream()方法时,返回一个输入流,用于从中读取服务器对于HTTP请求的返回信息。
⑦我们可以使用HttpURLConnection.connect()方法手动的发送一个HTTP请求,但是如果要获取HTTP响应的时候,请求就会自动的发起,比如我们使用HttpURLConnection.getInputStream()方法的时候,所以完全没有必要调用connect()方法。

二.HttpClient

1.基本介绍

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

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

2.使用流程

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

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

  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. 释放连接。无论执行方法是否成功,都必须释放连接

3.使用例子

3.1使用GET方式访问HTTP

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;


public class GetDemo {

public static void main(String[] args) {
    // 1. 创建HttpClient对象
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    // 2. 创建HttpGet对象
    HttpGet httpGet = new HttpGet(
            "http://localhost:8080/Servlet/do_login.do?username=test&password=123456");
    CloseableHttpResponse response = null;
    try {
        // 3. 执行GET请求
        response = httpClient.execute(httpGet);
        System.out.println(response.getStatusLine());
        // 4. 获取响应实体
        HttpEntity entity = response.getEntity();
        // 5. 处理响应实体
        if (entity != null) {
            System.out.println("长度:" + entity.getContentLength());
            System.out.println("内容:" + EntityUtils.toString(entity));
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 6. 释放资源
        try {
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
     		    }
  		   }
	   }
}

3.2使用POST方式访问HTTP

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
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.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class PostDemo {

public static void main(String[] args) {
    // 1. 创建HttpClient对象
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    // 2. 创建HttpPost对象
    HttpPost post = new HttpPost(
            "http://localhost:8080/Servlet/do_login.do");
    // 3. 设置POST请求传递参数
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("username", "test"));
    params.add(new BasicNameValuePair("password", "12356"));
    try {
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params);
        post.setEntity(entity);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    // 4. 执行请求并处理响应
    try {
        CloseableHttpResponse response = httpClient.execute(post);
        HttpEntity entity = response.getEntity();
        if (entity != null){
            System.out.println("响应内容:");
            System.out.println(EntityUtils.toString(entity));
        }
        response.close();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        try {
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
    	    }
  	  }
  }
}

3.3POST和GET的区别

HttpClient常用HttpGet和HttpPost这两个类,分别对应Get方式和Post方式。

HttpPost方法提交HTTP POST请求,需要使用HttpPost类的setEntity方法设置请求参数。参数则必须用NameValuePair[]数组存储。

get方式:以URL字串本身传递数据参数,在服务器端可以从’QUERY_STRING’这个变量中直接读取,效率较高,但缺乏安全性,也无法来处理复杂的数据。
post方式:就传输方式讲参数会被打包在数据包中传输,从CONTENT_LENGTH这个环境变量中读取,便于传送较大一些的数据,同时因为不暴露数据在浏览器的地址栏中,安全性相对较高,但这样的处理效率会受到影响。

4.使用总结

HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送HTTP请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性。

三.表单提交中的post和get方法的区别

1.get是从服务器上查询/获取数据,post是向服务器传输数据。
2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
4. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
5. get安全性非常低,传输数据可见,post安全性较高,传输数据不可见,但通过抓包工具post传递中的参数也可以看到,所以理论上也不是安全的。
6. get是Form的默认方法。

四.HttpURLConnection和HttpClient的区别

多数的网络链接应用都会用 HTTP 去发送数据和接收数据。

Android 包含了两个客户端:HttpURLConnection 和 Apache HTTP Client。
两种客户端都支持:Https、文件流上传/下载、超时、IPv6 和连接池。

1.HttpClient

优点:
HttpClient 非常适合 Web 浏览器。拥有丰富并且灵活的 API。实现方式都很好,并且几乎没有 Bug。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了。

缺点:
但也正因为拥有大量的 API,所以在不打破原有兼容性的情况下,是很难扩展的。
因此,Android 开发团队在 Apache HTTP Client 的开发上表现的不积极。

2.HttpURLConnection

优点:
相对于上面提到的 Apache HTTP Client 显得更通用、更轻量级。集中的 API 使得它更容易被扩展。

缺点:
方法少,基本只有如何发送请求、接收响应,以及管理HTTP连接。
在早期的一些版本中存在bug,尤其在关闭输入流时,可能导致连接池混乱。通过“关掉连接池”就可以避开这个Bug。

3.选择总结

在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。
而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。
对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值