Introduction
In my previous I setup the server side with mLTS https://magnus-k-karlsson.blogspot.com/2026/04/configure-mtlstwo-way-sslclient.html
SSL Bundle
application.properties
# https://docs.spring.io/spring-boot/reference/features/ssl.html
spring.ssl.bundle.jks.mybundle.truststore.location=file:src/test/resources/localhost.p12
spring.ssl.bundle.jks.mybundle.truststore.password=changeit
spring.ssl.bundle.jks.mybundle.keystore.location=file:src/test/resources/localhost.p12
spring.ssl.bundle.jks.mybundle.key.alias=localhost
spring.ssl.bundle.jks.mybundle.keystore.password=changeit
spring.ssl.bundle.jks.mybundle.keystore.type=PKCS12
RestClient Configuration
package se.magnuskkarlsson.clientcert;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.util.Timeout;
import org.springframework.boot.restclient.autoconfigure.RestClientSsl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestClient;
@Configuration
public class RestClientConfig {
// https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g
// https://docs.spring.io/spring-boot/api/java/org/springframework/boot/restclient/autoconfigure/RestClientSsl.html
// https://docs.spring.io/spring-boot/reference/features/ssl.html
// https://docs.spring.io/spring-boot/appendix/application-properties/index.html
@Bean
public RestClient restClient(RestClient.Builder restClientBuilder, RestClientSsl ssl) {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(150); // total connections
connectionManager.setDefaultMaxPerRoute(50); // per-host connections
RequestConfig requestConfig = RequestConfig.custom() //
.setConnectTimeout(Timeout.ofMilliseconds(2000)) // time to establish connection (ms)
.setResponseTimeout(Timeout.ofMilliseconds(3000)) // time waiting for server response (ms)
.setConnectionRequestTimeout(Timeout.ofMilliseconds(1000)) // time to wait for connection from pool (ms)
.build();
CloseableHttpClient httpClient = HttpClients.custom() //
.setConnectionManager(connectionManager) //
.setDefaultRequestConfig(requestConfig) //
.build();
return restClientBuilder //
.requestFactory(new HttpComponentsClientHttpRequestFactory(httpClient)) //
.apply(ssl.fromBundle("mybundle")) //
.baseUrl("https://localhost:8443") //
.build();
}
}
RestClient Code
@Autowired
RestClient restClient;
@Test
void hello() {
// https://dzone.com/articles/spring-boot-32-replace-your-resttemplate-with-rest
var response = restClient.get() //
.uri("/hello") //
.retrieve() //
.toEntity(String.class);
System.out.println(response.getBody());
}
No comments:
Post a Comment