【JAVA】HTTP协议结构以及Java实现GET和POST方法

1 HTTP协议8种方法

是基于请求-响应的模式TCP/IP协议的应用层协议。HTTP/1.1协议中共定义了八种方法来以不同方式操作指定的资源。

方法名称说明
GET一般用于查询信息。数据由URL进行传递,最大支持2K个字节
POST提交表单或者上传文件。数据被包含在请求体Body中。理论上数据不受限,不过不同Web服务器对post提交数据有限制
PUT向指定资源位置上传其最新内容
DELETE请求服务器删除Request-URL所标识的资源
HEAD与GET请求类似,仅返回消息头。
OPTIONS查询服务器对应url所支持的方法
TRACE回显服务器收到的请求,主要用于测试或诊断
CONNECTHTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器

2 HTTP协议报文结构

2.1 请求报文

下面是一个POST请求例子

POST /form/entry HTTP/1.1
Host: hackr.jp
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 16

可以将其划分为如下结构:
在这里插入图片描述
可大致将请求报文分为三部分:

  1. 请求行,包括方法、URL、协议版本号。
  2. 请求头(Headers),包括主机(Host)以及一些头部字段等。
  3. 实体内容(Body),根据(Content-Type)属性,内容格式也有所不同。

其中请求头常用的属性如下表所示

属性名称说明
Accept用于告诉服务器,客户机支持的数据类型 (例如:Accept:text/html,image/*)
Accept-Charset用于告诉服务器,客户机采用的编码格式
Accept-Encoding用于告诉服务器,客户机支持的数据压缩格式
Content-Type发送给接收者的实体正文的媒体类型(原生表单格式、json格式、多文件上传格式等)

比如设置Content-Type位json格式

Content-type: application/json; enconding=utf-8

则对应body中数据格式应该符合json格式

{
    "username": "Louis Lee",
    "password": "123456"
}

2.2 应答报文

下面是一个应答报文例子

HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html

可以将其划分为如下结构:
在这里插入图片描述

应答报文也分三部分

  1. 状态行,主要包括协议版本、状态码等信息
  2. 响应头部,一些属性信息,用于说明服务器所返回的消息
  3. 响应正文,根据响应头部中的媒体类型,该正文可以有不同的格式。

3 Java实现GET和POST方法

3.1 使用JAVA原生代码

3.1.1 GET请求

public String getRequest(String requestUrl){
    HttpURLConnection connection = null;
    InputStream is = null;
    BufferedReader br = null;
    String result = null;// 返回结果字符串
    try {
        // 创建远程url连接对象
        URL url = new URL(requestUrl);
        // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
        connection = (HttpURLConnection) url.openConnection();
        // 设置连接方式:get
        connection.setRequestMethod("GET");
        // 设置连接主机服务器的超时时间:15000毫秒
        connection.setConnectTimeout(15000);
        // 设置读取远程返回的数据时间:60000毫秒
        connection.setReadTimeout(60000);
        // 发送请求
        connection.connect();
        // 通过connection连接,获取输入流
        if (connection.getResponseCode() == 200) {
            is = connection.getInputStream();
            // 封装输入流is,并指定字符集
            br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            // 存放数据
            StringBuffer sbf = new StringBuffer();
            String temp = null;
            while ((temp = br.readLine()) != null) {
                sbf.append(temp);
                sbf.append("\r\n");
            }
            result = sbf.toString();
        }
    } catch (Exception e) {
        log.error("出错了:", e);
    } finally {
        // 关闭资源
        if (null != br) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (null != is) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        connection.disconnect();// 关闭远程连接
    }
    return result;
}

3.1.2 POST请求

public String postRequest(String requestUrl, String param){
    HttpURLConnection connection = null;
    InputStream is = null;
    OutputStream os = null;
    BufferedReader br = null;
    String result = null;
    try {
        URL url = new URL(requestUrl);
        // 通过远程url连接对象打开连接
        connection = (HttpURLConnection) url.openConnection();
        // 设置连接请求方式
        connection.setRequestMethod("POST");
        // 设置连接主机服务器超时时间:15000毫秒
        connection.setConnectTimeout(15000);
        // 设置读取主机服务器返回数据超时时间:60000毫秒
        connection.setReadTimeout(60000);

        // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
        connection.setDoOutput(true);
        // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
        connection.setDoInput(true);
        // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        // 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
        connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
        // 通过连接对象获取一个输出流
        os = connection.getOutputStream();
        // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
        os.write(param.getBytes());
        // 通过连接对象获取一个输入流,向远程读取
        if (connection.getResponseCode() == 200) {

            is = connection.getInputStream();
            // 对输入流对象进行包装:charset根据工作项目组的要求来设置
            br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

            StringBuffer sbf = new StringBuffer();
            String temp = null;
            // 循环遍历一行一行读取数据
            while ((temp = br.readLine()) != null) {
                sbf.append(temp);
                sbf.append("\r\n");
            }
            result = sbf.toString();
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (null != br) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != os) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != is) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 断开与远程地址url的连接
        connection.disconnect();
    }
    return result;
}

3.2 使用HttpClient工具

Maven依赖

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
</dependency>

3.2.1 GET请求

public static String doGet(String url) {
	CloseableHttpClient httpClient = null;
	CloseableHttpResponse response = null;
	String result = "";
	try {
	    // 通过址默认配置创建一个httpClient实例
	    httpClient = HttpClients.createDefault();
	    // 创建httpGet远程连接实例
	    HttpGet httpGet = new HttpGet(url);
	    // 设置配置请求参数
	    RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
	            .setConnectionRequestTimeout(35000)// 请求超时时间
	            .setSocketTimeout(60000)// 数据读取超时时间
	            .build();
	    // 为httpGet实例设置配置
	    httpGet.setConfig(requestConfig);
	    // 执行get请求得到返回对象
	    response = httpClient.execute(httpGet);
	    // 通过返回对象获取返回数据
	    HttpEntity entity = response.getEntity();
	    // 通过EntityUtils中的toString方法将结果转换为字符串
	    result = EntityUtils.toString(entity);
	    System.out.println(result);
	} catch (ClientProtocolException e) {
	    e.printStackTrace();
	} catch (IOException e) {
	    e.printStackTrace();
	} finally {
	    // 关闭资源
	    if (null != response) {
	        try {
	            response.close();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	    if (null != httpClient) {
	        try {
	            httpClient.close();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	}
	return result;
}

3.2.2 POST请求

public static String doPost(String url, Map<String, Object> paramMap) {
    CloseableHttpClient httpClient = null;
    CloseableHttpResponse httpResponse = null;
    String result = "";
    // 创建httpClient实例
    httpClient = HttpClients.createDefault();
    // 创建httpPost远程连接实例
    HttpPost httpPost = new HttpPost(url);
    // 配置请求参数实例
    RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
            .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
            .setSocketTimeout(60000)// 设置读取数据连接超时时间
            .build();
    // 为httpPost实例设置配置
    httpPost.setConfig(requestConfig);
    // 设置请求头
    httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
    // 封装post请求参数
    if (null != paramMap && paramMap.size() > 0) {
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        // 通过map集成entrySet方法获取entity
        Set<Map.Entry<String, Object>> entrySet = paramMap.entrySet();
        // 循环遍历,获取迭代器
        Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> mapEntry = iterator.next();
            nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
        }

        // 为httpPost设置封装好的请求参数
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    try {
        // httpClient对象执行post请求,并返回响应参数对象
        httpResponse = httpClient.execute(httpPost);
        // 从响应对象中获取响应内容
        HttpEntity entity = httpResponse.getEntity();
        result = EntityUtils.toString(entity);
        System.out.println(result);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (null != httpResponse) {
            try {
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != httpClient) {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return result;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java可以使用HTTPClient和HttpURLConnection两种方式来实现GET和POST请求。 使用HTTPClient的方法有两个版本,分别是HTTPClient3.1和HTTPClient4.5.5。HTTPClient3.1位于org.apache.commons.httpclient包下,而HTTPClient4.5.5位于org.apache.http.client包下。这两个版本都提供了对远程URL的操作工具包,可以满足工作需求。 另一种方式是使用HttpURLConnection,它是Java的标准请求方式。可以通过创建HttpURLConnection对象来发送GET和POST请求,并获取响应结果。 以下是使用HTTPClient和HttpURLConnection实现GET和POST请求的示例代码: 使用HTTPClient3.1实现GET请求: ```java HttpClient client = new HttpClient(); GetMethod method = new GetMethod(url); int statusCode = client.executeMethod(method); String response = method.getResponseBodyAsString(); ``` 使用HTTPClient4.5.5实现GET请求: ```java CloseableHttpClient client = HttpClients.createDefault(); HttpGet request = new HttpGet(url); CloseableHttpResponse response = client.execute(request); String result = EntityUtils.toString(response.getEntity()); ``` 使用HttpURLConnection实现GET请求: ```java URL url = new URL("http://example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); ``` 使用HTTPClient4.5.5实现POST请求: ```java CloseableHttpClient client = HttpClients.createDefault(); HttpPost request = new HttpPost(url); List<NameValuePair> params = new ArrayList<>(); params.add(new BasicNameValuePair("param1", "value1")); params.add(new BasicNameValuePair("param2", "value2")); request.setEntity(new UrlEncodedFormEntity(params)); CloseableHttpResponse response = client.execute(request); String result = EntityUtils.toString(response.getEntity()); ``` 使用HttpURLConnection实现POST请求: ```java URL url = new URL("http://example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); writer.write("param1=value1&param2=value2"); writer.flush(); int responseCode = connection.getResponseCode(); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); ``` 以上是使用Java实现GET和POST请求方法,可以根据具体需求选择适合的方式来发送请求并获取响应结果。\[1\]\[2\] #### 引用[.reference_title] - *1* [用Java实现GET,POST请求](https://blog.csdn.net/lianzhang861/article/details/80364549)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [JAVA的GET和POST请求实现方式](https://blog.csdn.net/u012513972/article/details/79569888)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路易斯·李

点个赞再走呗 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值