Skip to content

Commit ac81b15

Browse files
committed
Support JDK HttpClient in ClientHttpRequestFactories
This commit introduces support for the JdkClientHttpRequestFactory in ClientHttpRequestFactories.
1 parent cc23029 commit ac81b15

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
66

77
kotlinVersion=1.8.22
88
nativeBuildToolsVersion=0.9.23
9-
springFrameworkVersion=6.1.0-M1
9+
springFrameworkVersion=6.1.0-SNAPSHOT
1010
tomcatVersion=10.1.10
1111

1212
kotlin.stdlib.default.dependency=false

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.springframework.http.client.AbstractClientHttpRequestFactoryWrapper;
4646
import org.springframework.http.client.ClientHttpRequestFactory;
4747
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
48+
import org.springframework.http.client.JdkClientHttpRequestFactory;
4849
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
4950
import org.springframework.http.client.SimpleClientHttpRequestFactory;
5051
import org.springframework.util.Assert;
@@ -70,6 +71,10 @@ public final class ClientHttpRequestFactories {
7071

7172
private static final boolean OKHTTP_CLIENT_PRESENT = ClassUtils.isPresent(OKHTTP_CLIENT_CLASS, null);
7273

74+
static final String JDK_CLIENT_CLASS = "java.net.http.HttpClient";
75+
76+
private static final boolean JDK_CLIENT_PRESENT = ClassUtils.isPresent(JDK_CLIENT_CLASS, null);
77+
7378
private ClientHttpRequestFactories() {
7479
}
7580

@@ -87,6 +92,9 @@ public static ClientHttpRequestFactory get(ClientHttpRequestFactorySettings sett
8792
if (OKHTTP_CLIENT_PRESENT) {
8893
return OkHttp.get(settings);
8994
}
95+
if (JDK_CLIENT_PRESENT) {
96+
return Jdk.get(settings);
97+
}
9098
return Simple.get(settings);
9199
}
92100

@@ -111,6 +119,9 @@ public static <T extends ClientHttpRequestFactory> T get(Class<T> requestFactory
111119
if (requestFactoryType == OkHttp3ClientHttpRequestFactory.class) {
112120
return (T) OkHttp.get(settings);
113121
}
122+
if (requestFactoryType == JdkClientHttpRequestFactory.class) {
123+
return (T) Jdk.get(settings);
124+
}
114125
if (requestFactoryType == SimpleClientHttpRequestFactory.class) {
115126
return (T) Simple.get(settings);
116127
}
@@ -210,6 +221,33 @@ private static OkHttp3ClientHttpRequestFactory createRequestFactory(SslBundle ss
210221

211222
}
212223

224+
/**
225+
* Support for {@link JdkClientHttpRequestFactory}.
226+
*/
227+
static class Jdk {
228+
229+
static JdkClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) {
230+
java.net.http.HttpClient httpClient = createHttpClient(settings.connectTimeout(), settings.sslBundle());
231+
JdkClientHttpRequestFactory requestFactory = new JdkClientHttpRequestFactory(httpClient);
232+
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
233+
map.from(settings::readTimeout).asInt(Duration::toMillis).to(requestFactory::setReadTimeout);
234+
return requestFactory;
235+
}
236+
237+
private static java.net.http.HttpClient createHttpClient(Duration connectTimeout, SslBundle sslBundle) {
238+
java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder();
239+
if (connectTimeout != null) {
240+
builder.connectTimeout(connectTimeout);
241+
}
242+
if (sslBundle != null) {
243+
builder.sslContext(sslBundle.createSslContext());
244+
}
245+
return builder.build();
246+
}
247+
248+
249+
}
250+
213251
/**
214252
* Support for {@link SimpleClientHttpRequestFactory}.
215253
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.web.client;
18+
19+
import java.net.http.HttpClient;
20+
import java.time.Duration;
21+
22+
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
23+
import org.springframework.http.client.JdkClientHttpRequestFactory;
24+
import org.springframework.test.util.ReflectionTestUtils;
25+
26+
/**
27+
* Tests for {@link ClientHttpRequestFactories} when Apache Http Components is the
28+
* predominant HTTP client.
29+
*
30+
* @author Andy Wilkinson
31+
*/
32+
@ClassPathExclusions({ "httpclient5-*.jar", "okhttp-*.jar" })
33+
class ClientHttpRequestFactoriesJdkClientTests
34+
extends AbstractClientHttpRequestFactoriesTests<JdkClientHttpRequestFactory> {
35+
36+
ClientHttpRequestFactoriesJdkClientTests() {
37+
super(JdkClientHttpRequestFactory.class);
38+
}
39+
40+
@Override
41+
protected long connectTimeout(JdkClientHttpRequestFactory requestFactory) {
42+
HttpClient httpClient = (HttpClient) ReflectionTestUtils.getField(requestFactory, "httpClient");
43+
return httpClient.connectTimeout().map(Duration::toMillis).orElse(-1L);
44+
}
45+
46+
@Override
47+
@SuppressWarnings("unchecked")
48+
protected long readTimeout(JdkClientHttpRequestFactory requestFactory) {
49+
return (int) ReflectionTestUtils.getField(requestFactory, "readTimeout");
50+
}
51+
52+
}

0 commit comments

Comments
 (0)