Java 中的 HTTP 请求
原文:https://www.studytonight.com/java-examples/http-requests-in-java
HttpURLConnection
类是java.net
包的一部分,用于发送 HTTP 请求和获取响应。这是一个抽象类,扩展了URLConnection
类。该类提供基本功能。高级功能最好使用其他 HTTP 库。在本教程中,我们将学习如何使用这个类来处理 HTTP 请求。
使用 http 连接创建请求
要获取HttpURLConnection
类的实例,我们需要在 URL 上使用 openConnection() 方法。还需要显式强制转换。
我们可以通过在 HttpURLConnection 对象上使用 setRequestMethod() 来设置请求的类型。它可以采用以下值之一,默认值是 GET。
- 得到
- 邮政
- 头
- 选择
- 放
- 删除
- 微量
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
}
}
添加请求参数
我们可以向我们的 HTTP 请求添加请求或查询参数。我们首先需要使用 setDoOutput() 方法在连接对象上启用写入。然后我们可以获取数据输出流并向其写入字符串。字符串的格式必须为“参数 1=val1 &参数 2=val2 &参数 3=val3”。
import java.net.*;
import java.io.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.demo.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
String parameter = "param1=val1¶m2=val2";
DataOutputStream outputStream = (DataOutputStream)connection.getOutputStream();
outputStream.writeChars(parameter);
outputStream.flush();
outputStream.close();
}
}
我们可以通过编写一个方法来简化我们的工作,该方法采用一个 HashMap,并从映射的键值对中生成参数值字符串。
import java.net.*;
import java.io.*;
import java.util.*;
public class Demo
{
public static String addParameters(HashMap<String, String> parameters) throws Exception
{
StringBuilder sb = new StringBuilder();
for(Map.Entry<String, String> e : parameters.entrySet())
{
sb.append(URLEncoder.encode(e.getKey(), "UTF-8"));
sb.append("=");
sb.append(URLEncoder.encode(e.getValue(), "UTF-8"));
sb.append("&");
}
String params = sb.toString();
if(params.length() > 0)
return params.substring(0, params.length() - 1);
else
return params;
}
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.demo.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
HashMap<String, String> parameters = new HashMap<>();
parameters.put("param1", "val1");
parameters.put("param2", "val2");
parameters.put("param3", "val3");
String params = addParameters(parameters);
DataOutputStream outputStream = (DataOutputStream)connection.getOutputStream();
outputStream.writeChars(params);
outputStream.flush();
outputStream.close();
}
}
读取请求标题
为了读取请求头的值,我们在连接对象上使用 getHeaderField() 方法。此方法可以将标题字段的名称作为参数,并返回相应的值。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String date = connection.getHeaderField("Date");
System.out.print(date);
}
}
Fri,2021 年 8 月 6 日,格林尼治时间 02:52:29
我们也可以使用一个整数来获取第 n 个标题字段。使用 getHeaderFieldKey() 方法获取第 n 个头字段的名称。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String headerKey1 = connection.getHeaderFieldKey(1);
String headerField1 = connection.getHeaderField(1);
String headerKey2 = connection.getHeaderFieldKey(2);
String headerField2 = connection.getHeaderField(2);
System.out.println("Header Field 1: " + headerKey1 + "-->" + headerField1);
System.out.println("Header Field 2: " + headerKey2 + "-->" + headerField2);
}
}
标头字段 1:日期- > Fri,2021 年 8 月 6 日 02:52:29 格林尼治标准时间 标头字段 2:服务器->Apache/2 . 4 . 46(Unix)OpenSSL/1 . 1 . 1d
设置请求标题
我们可以在HttpURLConnection
实例上使用 setRequestProperty() 方法来设置请求头值。让我们设置连接和缓存控制头的值。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Cache-Control", "no-cache");
}
}
设置超时
我们可以使用 HttpURLConnection 类的 setConnectTimeout() 和 setReadTimeout() 方法来更改连接和读取的默认超时值。我们可以使用 getConnectTimeout() 和 getReadTimeout() 方法查看这些值。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
System.out.println("Default Timeout Values:");
System.out.println("Connect Timeout: " + connection.getConnectTimeout());
System.out.println("Read Timeout: " + connection.getReadTimeout());
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
//After
System.out.println("After Setting Timeout Values:");
System.out.println("Connect Timeout: " + connection.getConnectTimeout());
System.out.println("Read Timeout: " + connection.getReadTimeout());
}
}
默认超时值: 连接超时:0 读取超时:0 设置超时值后: 连接超时:10000 读取超时:10000
处理饼干
HttpCookie
和CookieManager
课程可以帮助我们使用饼干。为了读取 Cookie,我们可以获取 Set-Cookie 头的值,并使用 HttpCookie 类的 parse() 方法对其进行解析。
import java.net.*;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.gmail.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String cookieHeaderField = connection.getHeaderField("Set-Cookie");
List<HttpCookie> cookiesList = HttpCookie.parse(cookieHeaderField);
System.out.println(cookieHeaderField);
System.out.println(cookiesList);
}
}
Host-gap = 1:wozoyd 84 dr 89 kgux6-xfHQcJX0PpqA:KS-fe4ij 1w 4 gim;路径=/;到期=孙,06-2023 年 8 月 06 日 06:23:56 格林尼治标准时;安全;HttpOnly 优先级=高 [ 主机-间隙= 1:wozoyd 84 dr 89 kgux6-xfhqcjx0 ppqa:KS-fe4ij 1 w4 gim]
我们也可以在食谱中加入饼干。我们可以使用 CookieStore 来设置连接的 Cookie 请求属性。为此,我们需要关闭并重新打开我们的连接。
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.gmail.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String cookieHeaderField = connection.getHeaderField("Set-Cookie");
List<HttpCookie> cookiesList = HttpCookie.parse(cookieHeaderField);
CookieManager cm = new CookieManager();
cookiesList.forEach(cookie -> cm.getCookieStore().add(null, cookie));
connection.disconnect();
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Cookie",
StringUtils.join(cm.getCookieStore().getCookies(), ";"));
}
}
处理重定向
我们可以在 HttpURLConnection 实例上使用setinstancefloredirections()方法来启用或禁用重定向。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.google.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setInstanceFollowRedirects(true);
}
}
我们还可以通过使用setfollowsredirections()方法来启用或禁用所有连接的重定向。
HttpURLConnection.setFollowRedirects(true);
我们可以使用位置头字段来获取新的重定向网址。我们可以用它向新的重定向网址发送请求。请注意,重定向的响应代码是 301(永久移动)或 302(临时重定向)。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.google.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
boolean redirect = false;
if(connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM)
redirect = true;
if(redirect)
{
String redirectURL = connection.getHeaderField("Location");
URL newURL = new URL(redirectURL);
connection = (HttpURLConnection) newURL.openConnection();
}
}
}
阅读回应
HttpURLConnection 类提供了几种方法来读取对我们请求的响应。
读取响应代码和响应消息
我们可以在连接实例上使用 getResponseCode() 和 getResponseMessage() 方法来读取响应代码和响应消息。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
String responseMsg = connection.getResponseMessage();
System.out.print("Response Code: " + responseCode + " Response Message: " + responseMsg);
}
}
响应代码:200 响应消息:OK
读取响应标题
我们可以使用 getHeaderField() 方法来访问单个头字段。我们可以使用 getHeaderFields() 方法获取所有的头。它将返回一个映射集合。映射中的每个键表示标题字段,相应的值存储在列表中。
import java.net.*;
import java.util.List;
import java.util.Map;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
Map<String, List<String>> headerFields = connection.getHeaderFields();
for(Map.Entry<String, List<String>> e : headerFields.entrySet())
System.out.println(e.getKey() + "-->" + e.getValue());
}
}
传输-编码- >【分块】 保活- >【超时=5,最大= 100】 空->【HTTP/1.1 200 OK】 服务器->【Apache/2 . 4 . 46(Unix)OpenSSL/1 . 1 . 1d】 X-内容-类型-选项->【nosniff】 连接- >【保活】【T6 包括域名;预加载] 缓存-控制- >【无存储,无缓存,必须-重新验证】 Vary - >【接受-编码】 Set-Cookie->【phpsesid = 8 iqquicvn 5 ada 6 cjb1 ktkbjlcg;路径=/] 过期->【1981 年 11 月 19 日星期四格林尼治时间 08:52:00】 X-XSS-保护->【1;模式=块] 内容-类型- >【文本/html;charset = UTF-8] X-power-By->【PHP/7 . 4 . 15】
阅读回复内容
我们可以借助 HttpURLConnection 对象的 InputStream 读取响应内容。如果响应代码大于 200,那么我们将使用geterrortstream()方法。否则,请使用 getInputStream()方法。我们将使用BufferedReader
类来包装InputStreamReader
。
import java.net.*;
import java.io.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStreamReader isr;
if(connection.getResponseCode() > 299)
isr = new InputStreamReader(connection.getErrorStream());
else
isr = new InputStreamReader(connection.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
}
}
摘要
HTTP 连接类经常用于处理 HTTP 请求。这个类是 java.net 包的一部分,它扩展了 URLConnection 类。在本教程中,我们学习了这门课的基础知识。我们学习了如何从一个网址创建一个连接。我们学习了如何设置不同的属性和头值。我们还学习了如何读取响应状态、响应头和响应内容。