Http协议、HttpClient

HTTP请求协议包

http服务器

HTTP Server 也是我们常说的Web服务器

在网络中传递的信息都是以【二进制】形式存在的,接收方在接收信息后需要把二进制数据编译为原数据。

弊端:HTTP协议无法实现服务器主动向客户端发起消息。

http服务器需要

1、可以接收来自浏览器发送的Http请求协议包,并自动对Http请求协议包内容解析

2、并将定位的文件内容给写入到Http写入到HTTP响应协议包


请求协议包

在基于B/S结构下,互联网通信过程中,所有在网络中传递信息都是保存在HTTP网络协议包

浏览器 向 WEB服务器发送数据的时候,这个发送的数据需要遵循一套标准,这套标准中规定了发送的数据具体格式。

HTTP请求协议包自上而下划分为4个空间:请求行、请求头部、空行和请求数据4部分组成。


请求行

请求行主要提供:请求地址请求方式、HTTP 协议版本字段

Http协议、HttpClient_第1张图片

Get方式参数存放在请求数据包的请求行的URI字段中,

以?开始,以param=value¶me2=value2的形式附加在URI字段之后


请求头

请求头部:格式为“属性名:属性值”,每行一对。请求头部通知服务器有关于客户端请求的信息,常见的如下:

  1. Authorization:常用于传递身份验证凭证,如基本认证(Basic Authentication)或令牌(Token)。服务器可以根据这些凭证对请求进行身份验证,以确定是否允许访问受保护的资源。

  2. Content-Type:指定了请求体中数据的格式类型,如JSON、表单数据等。服务器可以根据Content-Type来正确解析请求体中的数据。

其他典型的请求头还有:

  ● User-Agent:产生请求的浏览器和操作系统信息;

  ● Accept:客户端可识别的响应内容类型列表;星号 “ * ” 用于按范围将类型分组,用 “ */* ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型;

  ● Accept-Language:客户端可接受的自然语言;

  ● Accept-Encoding:客户端可接受的编码压缩格式;

  ● Accept-Charset:可接受的应答的字符集;

  ● Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;

  ● connection:连接方式(close 或 keepalive);

  ● Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;
       ● Referer:指示了当前请求是从哪个URL页面发起的,可以帮助服务器识别请求的来源。

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

x-forwarded-for:是一个 HTTP 扩展头部,主要是为了让 Web 服务器获取访问用户的真实 IP 地址

X-Forwarded-For 请求头格式

X-Forwarded-For: client, proxy1, proxy2

可以看到,XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP(用户真实 IP),然后是每一级代理设备的 IP。

 public static String getIpAddr(HttpServletRequest request) {
     if (request == null) {
         return "unknown";
     }
     String ip = request.getHeader("x-forwarded-for");
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
         ip = request.getHeader("Proxy-Client-IP");
     }
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
         ip = request.getHeader("X-Forwarded-For");
     }
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
         ip = request.getHeader("WL-Proxy-Client-IP");
     }
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
         ip = request.getHeader("X-Real-IP");
     }
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
         ip = request.getRemoteAddr();
     }
     return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
 }

CONTENT_TYPE


空白行和请求体

空白行:没有任何内容。是用来区分"请求头"和"请求体"的

请求体:如果请求方式是post,那么请求参数信息会保存到请求体中


HTTP响应协议包

响应协议包

WEB服务器 向 浏览器发送数据的时候,这个发送的数据需要遵循一套标准,这套标准中规定了发送的数据具体格式。


状态行

HTTP状态码

Http协议、HttpClient_第2张图片


响应头

Content-Type:指定浏览器采用对应编译器对响应体二进制数据进行解析

Http协议、HttpClient_第3张图片


空白行和响应体

空白行:区分"响应头"和"响应体"

响应体:可能是被访问静态资源文件内容,可能是动态资源文件的运行结果


HttpClient

多种请求方法

HTTP 请求可以使用多种请求方法。

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

1 GET 请求指定的页面信息,并返回实体主体。
2 HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5 DELETE 请求服务器删除指定的页面。
6 CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7 OPTIONS 允许客户端查看服务器的性能。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。
9 PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新 。

pom依赖引入

HttpClient 是Apache HttpComponents 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
spring boot集成HttpClient


	org.apache.httpcomponents
	httpclient

如果是maven工程,引入如下maven依赖



    org.apache.httpcomponents.client5
    httpclient5
    5.1.1

响应处理

在 HttpClient 中把响应封装成了 CloseableHttpResponse 对象,在此对象中可以获取如下数据:

  1. getCode() 获取响应状态
  2. getEntity() 获取响应数据

HttpClient 提供了 EntityUtils工具类,可以很好的把 响应的 HttpEntity 转换为 字节数组或者字符串

// 转换为字符串
EntityUtils.toString(response.getEntity());

// 转换为字节数组
EntityUtils.toByteArray(response.getEntity());

调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。


GET请求

GET请求的所有参数是直接拼接在 URL 后面的,在浏览器地址栏中可见。

GET请求url编码

使用GET请求时会将参数附加到URL的查询字符串中,以便将其发送给服务器。但是GET请求只接受ASCII字符作为参数值。

解决办法:

GET请求会把参数进行URL编码(也称为百分号编码或URL转义),以确保特殊字符不会干扰URL结构。

如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

 public static void main(String[] args) throws Exception {
     //获取默认配置的 HttpClient
     CloseableHttpClient httpclient = HttpClients.createDefault();
     //设置单个请求的配置信息
     RequestConfig requestConfig = RequestConfig.custom()
             // 设置连接超时时间
             .setConnectTimeout(Timeout.of(3000, TimeUnit.MILLISECONDS))
             // 设置响应超时时间
             .setResponseTimeout(3000, TimeUnit.MILLISECONDS)
             // 设置从连接池获取链接的超时时间
             .setConnectionRequestTimeout(3000, TimeUnit.MILLISECONDS)
             .build();
     // 请求路径及参数
     String name = URLEncoder.encode("张三", "utf-8");
     String url = "http://localhost:10010/user/params?age=20&name=" + name;
     HttpGet httpget = new HttpGet(url);
     httpget.setConfig(requestConfig);
     // 调用 HttpClient 的 execute 方法执行请求
     CloseableHttpResponse response = httpclient.execute(httpget);
     try {
         HttpEntity entity = response.getEntity();
         String result = EntityUtils.toString(entity);
         EntityUtils.consume(entity);
         System.out.println(result);
     } finally {
         response.close();
     }
 }

通过 URIBuilder 构建请求路径


POST请求(表单方式)

使用POST请求时,参数通过HTTP消息体进行传输,并不会直接显示在URL上。POST支持多种编码方式。具体的数据格式和编码方式由 Content-Type 字段确定。服务端会根据 Content-Type 字段使用不同的方式对请求体进行解析。

最常用的POST数据编码方式是 application/x-www-form-urlencoded ,它与GET相似,也会对非ASCII字符和特殊字符进行URL编码。

这种方式下,参数按照键值对形式出现在消息正文中,并用&符号连接起来,同时以 = 分隔键和值,

HTTP 中的 POST 请求的数据是包含在请求体中的。在 HttpClient 中 POST 请求发送数据是通过,调用 HttpPost 类的 setEntity(HttpEntity entity) 方法设置消息内容的

public static void main(String[] args) throws Exception {
    // 创建 ContentType 对象为 form 表单模式
    ContentType contentType = ContentType.create("application/x-www-form-urlencoded", StandardCharsets.UTF_8);
    String url = "http://localhost:10010/user/body";
    HttpPost httpPost = new HttpPost(url);
    //设置请求头,添加到 HttpPost 头中
    httpPost.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
    //HttpPost请求 要传的参数 这里先将参数封装起来
    List params = new ArrayList<>();
    params.add(new BasicNameValuePair("name", "张三"));
    params.add(new BasicNameValuePair("age", "20"));
    //这一步才是 为post 请求设置参数  这是创建表单的实体对象 设置当前参数的编码格式
    //设置请求数据,把HttpEntity 设置到 HttpPost 中
    httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
    //获取默认配置的 HttpClient
    CloseableHttpClient httpclient = HttpClients.createDefault();
    //调用 HttpClient 的 execute 方法执行请求
    CloseableHttpResponse response = httpclient.execute(httpPost);
    try {
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity);
        EntityUtils.consume(entity);
        System.out.println(result);
    } finally {
        response.close();
    }
}

consume()这个方法,其功能就是关闭HttpEntity是的流,


POST请求(Json方式)

application/json 是一种常用的HTTP请求头,用于指定请求的内容类型为JSON格式

使用 application/json 编码方式,可以将数据序列化成一个 JSON 字符串作为请求主体。

public static void main(String[] args) throws Exception {
    // 创建 ContentType 对象为 form 表单模式
    ContentType contentType = ContentType.create("application/json", StandardCharsets.UTF_8);
    String url = "http://localhost:10010/user/body";
    HttpPost httpPost = new HttpPost(url);
    //设置请求头,添加到 HttpPost 头中
    httpPost.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
    //设置报文和通讯格式
    String jsonParam = "{\"name\":\"John\", \"age\":30}";
    StringEntity stringEntity = new StringEntity(jsonParam, StandardCharsets.UTF_8);
    httpPost.setEntity(stringEntity);
    //获取默认配置的 HttpClient
    CloseableHttpClient httpclient = HttpClients.createDefault();
    //调用 HttpClient 的 execute 方法执行请求
    CloseableHttpResponse response = httpclient.execute(httpPost);
    try {
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity);
        EntityUtils.consume(entity);
        System.out.println(result);
    } finally {
        response.close();
    }
}


POST请求(文件上传)

multipart/form-data

这种编码方式主要用于文件上传,可以有效地传输二进制(非字母数字)数据,同时还可以携带其他信息

最常见的 POST 提交数据的方式,也是典型的key-val键值对,无需转化,在request中直接获取,框架也会将同名属性封装到接收对象中,支持文件流上传

如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。

但是如果有type=file的话,就要用到multipart/form-data了。

4、 application/octet-stream

 二进制流数据(如常见的文件下载)

你可能感兴趣的:(http,网络协议,网络)