在Java中,发送HTTP请求的方式主要有以下几种:
-
使用
java.net.HttpURLConnection
类:
HttpURLConnection是Java中用于发送HTTP请求和接收HTTP响应的类。它是java.net包中的一部分,基于Java的网络编程API。
HttpURLConnection的一些常用参数和方法如下:请求方法(Request Method): GET:获取资源。 POST:提交数据。 PUT:更新资源。 DELETE:删除资源。 HEAD:获取资源的头部信息。 OPTIONS:获取服务器支持的请求方法。 TRACE:回显服务器收到的请求,用于测试和诊断。 请求头(Request Headers): setRequestProperty(String key, String value):设置请求头的键值对。 请求体(Request Body): setDoOutput(true):允许向服务器发送请求体。 getOutputStream():获取输出流,用于写入请求体数据。 响应状态(Response Status): getResponseCode():获取响应状态码。 getResponseMessage():获取响应状态消息。 响应头(Response Headers): getHeaderField(String name):获取指定名称的响应头的值。 getHeaderFields():获取所有响应头的键值对。 响应体(Response Body): getInputStream():获取输入流,用于读取响应体数据。 连接和关闭: connect():建立与服务器的连接。 disconnect():关闭连接。
URL url = new URL("http://example.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000); // 设置连接超时时间为5秒
conn.setReadTimeout(5000); // 设置读取超时时间为5秒
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println("Response Body: " + response.toString());
connection.disconnect();
优点:这是Java标准库提供的方法,不需要额外的依赖。
缺点:使用起来比较繁琐,需要手动处理连接、读取响应等操作。
- 使用
java.net.http.HttpClient
类(Java 11及以上版本):
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
优点:这是Java 11新引入的HTTP客户端,支持HTTP/2,API设计更现代,使用起来更简洁。
缺点:只有Java 11及以上版本才提供。
-
使用Apache HttpClient库:
HttpClient的体系结构主要包括以下几个核心组件:HttpClient:代表整个HTTP客户端,负责发送HTTP请求和处理HTTP响应。 HttpRequest:代表一个HTTP请求,包括请求方法、URL、请求头、请求体等信息。 HttpResponse:代表一个HTTP响应,包括响应状态、响应头、响应体等信息。 HttpEntity:代表HTTP请求或响应的实体,可以是文本、二进制数据、文件等。 HttpClientBuilder:用于创建和配置HttpClient实例的构建器。 RequestConfig:用于配置请求的参数,例如连接超时时间、读取超时时间、代理等。 HttpClientContext:用于传递上下文信息,例如Cookie、认证信息等。 HttpClient的参数可以通过HttpClientBuilder和RequestConfig进行配置。下面是一些常见的参数: 连接参数: 连接超时时间(Connect Timeout):设置建立连接的最大等待时间。 读取超时时间(Socket Timeout):设置从服务器读取数据的最大等待时间。 连接池大小(Connection Pool Size):设置连接池的最大连接数。 路由最大连接数(Max Connections per Route):设置每个目标主机的最大连接数。 重试参数: 重试次数(Retry Count):设置请求失败时的最大重试次数。 重试间隔(Retry Interval):设置重试之间的时间间隔。 认证参数: 代理认证(Proxy Authentication):设置代理服务器的认证信息。 目标主机认证(Target Host Authentication):设置目标主机的认证信息。 Cookie管理: Cookie存储(Cookie Store):用于保存和管理Cookie。 Cookie策略(Cookie Policy):设置处理Cookie的策略,例如接受所有Cookie、只接受来自同一域的Cookie等。
引入jar
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
public class HttpClientSingleton {
private static CloseableHttpClient httpClient;
private HttpClientSingleton() {}
public static synchronized CloseableHttpClient getInstance() {
if (httpClient == null) {
// 创建 HttpClient 实例并进行配置
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)// 设置连接超时时间为5秒
.setSocketTimeout(5000)// 设置读取超时时间为5秒
.build();
SSLConnectionSocketFactory sslConnectionSocketFactory = null;
try {
sslConnectionSocketFactory = new SSLConnectionSocketFactory(MyBeanConfig.getSslcontext(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.register("http", new PlainConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connectionManager.setMaxTotal(10); // 设置连接池的最大连接数为10
connectionManager.setDefaultMaxPerRoute(2);// 每个路由的最大连接数
HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(3, true); // 设置最大重试次数为3次
CookieStore cookieStore = new BasicCookieStore();//设置cookie
httpClientBuilder.setDefaultRequestConfig(requestConfig);
httpClientBuilder.setConnectionManager(connectionManager);
httpClientBuilder.setRetryHandler(retryHandler);
httpClientBuilder.setDefaultCookieStore(cookieStore);
httpClient = httpClientBuilder.build();
}
return httpClient;
}
public static void main(String[] arg) {
CloseableHttpClient client = getInstance();
HttpGet request = new HttpGet("http://example.com");
CloseableHttpResponse response = client.execute(request);
String resultString = EntityUtils.toString(execute.getEntity(), "utf-8");
System.out.print(resultString);
}
}
优点:功能强大,支持各种HTTP方法、自定义请求头、连接池等。
缺点:需要额外引入Apache HttpClient依赖,使用起来相对复杂。
-
使用OkHttp库:
OkHttpClient是Square公司开发的一款基于OkHttp库的HTTP客户端,它提供了丰富的功能和灵活的配置选项。OkHttpClient的主要组成部分包括:Dispatcher:负责调度HTTP请求和响应的处理线程。它可以同时处理多个请求,并根据配置的最大请求数进行限制。 ConnectionPool:负责管理HTTP连接的连接池。它可以重用已经建立的连接,避免了每次请求都需要重新建立连接的开销。 Interceptor:负责对请求和响应进行拦截和处理。Interceptor可以在请求发送之前和响应返回之后对数据进行修改和处理。 Authenticator:负责处理HTTP身份验证。它可以根据服务器返回的身份验证要求,自动进行身份验证操作。 DNS:负责解析主机名。它可以将主机名解析为对应的IP地址,以便建立HTTP连接。
引入jar
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.9</version>
</dependency>
import okhttp3.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class OkHttpClientSingleton {
private static OkHttpClient okHttpClient;
private OkHttpClientSingleton() {}
public static synchronized OkHttpClient getInstance() throws NoSuchAlgorithmException, KeyManagementException {
if (okHttpClient == null) {
// 创建一个信任所有证书的TrustManager
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
// 创建一个SSLContext,并使用上面的TrustManager初始化
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// 使用上面创建的SSLContext创建一个SSLSocketFactory
javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
// 创建 OkHttpClient 实例并进行配置
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.connectionPool(new ConnectionPool(10, 2, TimeUnit.MINUTES));//设置连接池的参数,包括最大连接数、连接的存活时间等。
builder.connectTimeout(10, TimeUnit.SECONDS); //设置建立连接的超时时间
builder.readTimeout(10, TimeUnit.SECONDS); //设置从服务器读取数据的超时时间
builder.writeTimeout(10, TimeUnit.SECONDS); //设置向服务器写入数据的超时时间
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(10);
dispatcher.setMaxRequestsPerHost(5);
builder.dispatcher(dispatcher); //设置同时能够处理的最大请求数
Interceptor interceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 对请求进行修改
Request modifiedRequest = request.newBuilder()
.header("Authorization", "Bearer token")
.build();
// 发送修改后的请求
Response response = chain.proceed(modifiedRequest);
// 对响应进行处理
return response;
}
};
builder.addInterceptor(interceptor);//添加请求和响应的拦截器,可以对数据进行修改和处理
okHttpClient = builder.build();
}
return okHttpClient;
}
public static void main(String[] arg) {
OkHttpClient client = getInstance();
Request request = new Request.Builder()
.url("http://example.com")
.addHeader("User-Agent", "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
.build();
Response response = client.newCall(request).execute();
System.out.print(execute.message());
System.out.print(execute.body().bytes());
}
}
优点:API设计现代,使用简洁,支持同步和异步请求,支持HTTP/2。
缺点:需要额外引入OkHttp依赖。
5.使用restTemplate
RestTemplate使用了HttpClient库作为底层的请求工具,HttpClient也提供了连接池的支持。HttpClient的连接池默认情况下是开启的,可以通过配置参数来调整连接池的大小和超时时间。
@Bean("restTemplate")
public RestTemplate getRestTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// 创建 RestTemplate 默认情况下,它会使用Apache HttpClient作为底层的HTTP客户端库
// 创建 HttpClientBuilder 对象
HttpClientBuilder httpClientBuilder = HttpClients.custom();
SSLConnectionSocketFactory sslConnectionSocketFactory = null;
try {
sslConnectionSocketFactory = new SSLConnectionSocketFactory(getSslcontext(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.register("http", new PlainConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connectionManager.setMaxTotal(10);// 最大连接数
connectionManager.setDefaultMaxPerRoute(2);// 每个路由的最大连接数
httpClientBuilder.setConnectionManager(connectionManager);
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build());
factory.setConnectTimeout(1*1000);//建立连接的超时时间
factory.setReadTimeout(1*1000);//从服务器读取数据的超时时间
//ignoreSSL();
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setMessageConverters(Arrays.<HttpMessageConverter<?>>asList(new MappingJackson2HttpMessageConverter(), new StringHttpMessageConverter()));// 消息转换器(setMessageConverters):设置请求和响应的消息转换器
restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); // 错误处理器(setErrorHandler):设置请求过程中的错误处理器
return restTemplate;
}
@Qualifier("restTemplate")
@Autowired
private RestTemplate restTemplate;
@Test
public void t1() throws KeyManagementException, NoSuchAlgorithmException {
// 使用 RestTemplate 发送请求
//MyBeanConfig.ignoreSSL();
ResponseEntity<String> response = restTemplate.getForEntity("http://example.com", String.class);
System.out.print(response.getStatusCode());
System.out.print(response.getBody());
}
6.使用httpclient
引入jar
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
public class HttpTest2 {
public static void main(String[] args) {
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod("http://example.com");
postMethod.addRequestHeader("accept", "*/*");
postMethod.addRequestHeader("Content-Type", "application/json");
Map paraMap = new HashMap();
paraMap.put("id", "1");
postMethod.addParameter("serviceName", "queryMerchantService");
postMethod.addParameter("params", JSON.toJSONString(paraMap));
String result = "";
try {
int code = httpClient.executeMethod(postMethod);
if (code == 200){
result = postMethod.getResponseBodyAsString();
System.out.println("result:" + result);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
以上就是Java中发送HTTP请求的主要方式,各有优点和缺点,可以根据具体需求选择使用。
版权声明:本文为博主作者:m0_38051458原创文章,版权归属原作者,如果侵权,请联系我们删除!
原文链接:https://blog.csdn.net/m0_38051458/article/details/132204834