Http协议、HttpClient

发布时间:2024年01月14日

HTTP请求协议包

http服务器

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

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

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

http服务器需要

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

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


请求协议包

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

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

HTTP请求协议包自上而下划分为4个空间


请求行

请求行主要提供:请求地址请求方式

get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value&parame2=value2的形式附加在URI字段之后


请求头

如果请求方式是get,那么请求参数信息会保存到请求头中

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状态码


?响应头

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


空白行

区分"响应头"和"响应体"


响应体

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


多种请求方法

9种请求方法

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

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

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

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

HttpClient

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

创建HttpClient对象。
创建请求方式的实例。创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
添加请求参数。如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
发送Http请求。调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
获取返回的内容。调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
释放资源。无论执行方法是否成功,都必须释放资源;
spring boot集成HttpClient

<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
</dependency>

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

<!-- 此处使用的是 5.x 版本,可以根据自身情况引入版本 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.1.1</version>
</dependency>

HttpClient 响应处理

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

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

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

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

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

1


GET请求

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

GET请求url编码

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

解决办法:

GET请求会把参数进行URL编码(也称为百分号编码或URL转义),以确保特殊字符不会干扰URL结构。
 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 类型对于处理 POST 请求至关重要,它可以帮助我们更好地使用和解决问题。

请求头字段有?Content-Type

具体的数据格式和编码方式由?Content-Type?字段确定。服务端会根据 Content-Type 字段使用不同的方式对请求体进行解析。

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

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

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<BasicNameValuePair> 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();
    }
}

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

3、multipart/form-data

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

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

发送 JSON 数据

文章来源:https://blog.csdn.net/m0_56799642/article/details/135580886
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。