Java 实现HTTP请求

从 JDK 11 开始,Java 为执行 HTTP 请求提供了一个新的 API,它是用来替代 HttpUrlConnection 的,即HttpClient API。

HttpUrlConnection

HttpUrlConnection 类允许我们执行基本的 HTTP 请求,而无需使用任何额外的库。我们需要的所有类都是 java.net 包的一部分。

使用这种方法的缺点是,代码可能比其他的HTTP库更繁琐,而且它不提供更高级的功能,如添加头文件或认证的专用方法。

1.创建一个请求

我们可以使用 URL 类的 openConnection() 方法创建一个 HttpUrlConnection 实例。注意,这个方法只是创建一个连接对象,但还没有建立连接。

HttpUrlConnection 类通过将 requestMethod 属性设置为get, post, head, options, put, delete, trace其中一个值。

让我们使用GET方法创建一个与给定URL的连接:

URL url = new URL("https://www.XXXXX.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");

2.添加请求参数

如果我们想向一个请求添加参数,我们必须将 doOutput 属性设置为 true,然后向 HttpUrlConnection 实例的OutputStream 写一个类似 param1=value&param2=value 的字符串。

Map<String, String> parameters = new HashMap<>();
parameters.put("param1", "val");

con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(parameters));
out.flush();
out.close();

为了方便参数Map的转换,我们编写了一个名为ParameterStringBuilder的实用类,其中包含一个静态方法getParamsString(),可以将Map转换为所需格式的字符串。

public class ParameterStringBuilder {
    public static String getParamsString(Map<String, String> params) 
      throws UnsupportedEncodingException{
        StringBuilder result = new StringBuilder();

        for (Map.Entry<String, String> entry : params.entrySet()) {
          result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
          result.append("=");
          result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
          result.append("&");
        }

        String resultString = result.toString();
        return resultString.length() > 0 ? resultString.substring(0, resultString.length() - 1) : resultString;
    }
}

3.设置请求头信息

通过使用 setRequestProperty() 方法可以实现在请求中添加头信息。

con.setRequestProperty("Content-Type", "application/json");

要从一个连接中读取一个头的值,我们可以使用 getHeaderField() 方法。

String contentType = con.getHeaderField("Content-Type");

4.配置超时

HttpUrlConnection 类允许设置连接和读取超时。这些值定义了等待与服务器的连接建立或数据可被读取的时间间隔。

为了设置超时值,我们可以使用 setConnectTimeout()和 setReadTimeout()方法。

con.setConnectTimeout(5000); #单位毫秒
con.setReadTimeout(5000); #单位毫秒

在这个例子中,我们把两个超时值都设为5秒。

5.处理Cookie

java.net 包包含了便于处理 cookie 的类,如 CookieManager 和 HttpCookie。

首先,为了从响应中读取 cookie,我们可以检索 Set-Cookie 头的值,并将其解析为一个 HttpCookie 对象的列表。

String cookiesHeader = con.getHeaderField("Set-Cookie");
List<HttpCookie> cookies = HttpCookie.parse(cookiesHeader);

接下来,我们将把cookie添加到cookieStore。

cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));

让我们检查一下是否有一个叫做 username 的 cookie,如果没有,我们将把它添加到cookieStore,其值为 “javanorth”。

Optional<HttpCookie> usernameCookie = cookies.stream().findAny().filter(cookie -> cookie.getName().equals("username"));
if (usernameCookie == null) {
    cookieManager.getCookieStore().add(null, new HttpCookie("username", "javanorth"));
}

最后,为了在请求中加入 cookie,我们需要在关闭和重新打开连接后设置 Cookie 头。

con.disconnect();
con = (HttpURLConnection) url.openConnection();

con.setRequestProperty("Cookie", StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));

6.处理重定向

我们可以通过使用参数为 true 或 false 的 setInstanceFollowRedirects() 方法,为一个特定的连接启用或禁用自动跟踪重定向。

con.setInstanceFollowRedirects(false);

也可以启用或禁用所有连接的自动重定向。

HttpUrlConnection.setFollowRedirects(false);

默认情况下,该行为是启用的。

当一个请求返回状态代码 301 或 302,表示重定向时,我们可以检索位置头并创建一个新的请求到新的URL。

if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) {
    String location = con.getHeaderField("Location");
    URL newUrl = new URL(location);
    con = (HttpURLConnection) newUrl.openConnection();
}

7.读取响应

读取请求的响应可以通过解析 HttpUrlConnection 实例的 InputStream 来完成。

为了执行请求,我们可以使用 getResponseCode()、connect()、getInputStream() 或 getOutputStream() 方法。

int status = con.getResponseCode();

最后,让我们读一下请求的响应,并把它放在一个内容字符串中。

BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    content.append(inputLine);
}
in.close();

要关闭连接,我们可以使用 disconnect() 方法。

con.disconnect();

8.在失败的请求中读取响应

如果请求失败了,我们从 HttpUrlConnection 实例的 InputStream 读取是读取不到数据的。我们可以从 HttpUrlConnection.getErrorStream() 提供的流读取。

我们可以通过比较 HTTP 状态码来决定使用哪个 InputStream。


int status = con.getResponseCode();

Reader streamReader = null;

if (status > 299) {
    streamReader = new InputStreamReader(con.getErrorStream());
} else {
    streamReader = new InputStreamReader(con.getInputStream());
}

最后,我们可以用与上一节相同的方式读取 streamReader。

Java中,有多种方式可以实现HTTP请求。其中一种常见的方式是使用Java标准库中的HttpURLConnection类。这个类提供了发送HTTP请求和接收HTTP响应的功能。你可以使用HttpURLConnection类创建连接,并设置请求方法、请求头、请求体等,然后发送请求并获取响应。具体的代码可以参考以下示例: ``` import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class HttpExample { public static void main(String[] args) throws IOException { URL url = new URL("https://www.example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); // 设置请求方法,例如GET、POST等 connection.setConnectTimeout(5000); // 设置连接超时时间 connection.setReadTimeout(5000); // 设置读取超时时间 int responseCode = connection.getResponseCode(); // 获取响应码 if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = connection.getInputStream(); // 处理响应数据 } else { // 处理错误情况 } connection.disconnect(); // 断开连接 } } ``` 另外,你还可以使用第三方库来简化HTTP请求的过程,比如OkHttp和Spring的RestTemplate。使用OkHttp时,你可以创建一个OkHttpClient实例,并使用Request类来构建请求,然后发送请求并获取响应。以下是一个使用OkHttp的示例代码: ``` import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import java.io.IOException; public class OkHttpExample { private static final OkHttpClient client = new OkHttpClient(); public static void main(String[] args) throws IOException { Request request = new Request.Builder() .url("https://www.example.com") .build(); try (Response response = client.newCall(request).execute()) { String result = response.body().string(); System.out.println(result); } } } ``` 如果你使用Spring框架,你可以使用RestTemplate类来发送HTTP请求。RestTemplate封装了HTTP请求的各种方法,让你可以更方便地发送请求和处理响应。以下是一个使用RestTemplate的示例代码: ``` import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; public class RestTemplateExample { public static void main(String[] args) { RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> response = restTemplate.getForEntity("https://www.example.com", String.class); String result = response.getBody(); System.out.println(result); } } ``` 以上是三种常见的Java实现HTTP请求的方法,你可以根据具体的需求选择适合的方式来发送HTTP请求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Java 实现HTTP请求的四种方式总结](https://blog.csdn.net/qq_34383510/article/details/130627924)[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^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值