如何使用Spring Boot向HTTP2微服务发送POST请求?
Hey there! Sending a POST request to an HTTP/2-enabled Undertow microservice in Spring Boot is totally straightforward, and there are a couple of go-to approaches you can use. Let me break them down for you, plus the key configuration details to make sure HTTP/2 works as expected:
WebClient is Spring's modern, reactive HTTP client that has native support for HTTP/2 when paired with a compatible underlying connector like Reactor Netty. Here's how to set it up:
Step 1: Configure the WebClient Bean
First, create a configuration class to build a WebClient that uses HTTP/2:
import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.HttpProtocol; import reactor.netty.http.client.HttpClient; @Configuration public class WebClientConfig { @Bean public WebClient http2WebClient() { // Build an HTTP client that enforces HTTP/2 HttpClient httpClient = HttpClient.create() .protocol(HttpProtocol.H2) .secure(sslSpec -> sslSpec .sslContext(SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE))); // *Note: Don't use the insecure trust manager in production!* // Replace it with code that loads your trusted SSL certificates instead. return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .baseUrl("https://your-undertow-service-base-url") // Use HTTPS for standard HTTP/2 .build(); } }
Step 2: Send the POST Request
Inject the configured WebClient into your service or controller and use it to send the POST request:
import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @Service public class Http2PostService { private final WebClient http2WebClient; // Constructor injection (preferred over field injection) public Http2PostService(WebClient http2WebClient) { this.http2WebClient = http2WebClient; } public Mono<YourResponseDto> sendPostRequest(YourRequestDto requestBody) { return http2WebClient.post() .uri("/your-target-endpoint-path") .bodyValue(requestBody) // Pass your request body DTO .retrieve() .bodyToMono(YourResponseDto.class); // Map response to your DTO } }
If you're still using RestTemplate (Spring's older synchronous client), you'll need to configure it to use an HTTP/2-compatible client library like Apache HttpClient 5. Here's how:
Step 1: Add Dependencies
First, add these dependencies to your pom.xml (Maven) or build.gradle (Gradle):
<!-- Maven --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents.core5</groupId> <artifactId>httpcore5-h2</artifactId> </dependency>
Step 2: Configure the RestTemplate Bean
Create a configuration class to build a RestTemplate that supports HTTP/2:
import org.apache.hc.client5.http.impl.nio.CloseableHttpAsyncClient; import org.apache.hc.client5.http.impl.nio.HttpAsyncClients; import org.apache.hc.client5.http.nio.ssl.ClientTlsStrategy; import org.apache.hc.core5.http.config.Registry; import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.nio.ssl.TlsStrategy; import org.apache.hc.core5.ssl.SSLContexts; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @Configuration public class RestTemplateConfig { @Bean public RestTemplate http2RestTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(null, (chain, authType) -> true) // Insecure for testing only! .build(); Registry<TlsStrategy> tlsStrategyRegistry = RegistryBuilder.<TlsStrategy>create() .register("h2", ClientTlsStrategy.create()) .register("https", ClientTlsStrategy.create()) .build(); CloseableHttpAsyncClient asyncClient = HttpAsyncClients.custom() .setTlsStrategy(tlsStrategyRegistry) .setSSLContext(sslContext) .build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(asyncClient); return new RestTemplate(requestFactory); } }
Step 3: Send the POST Request
Inject the RestTemplate and use it to send your POST request:
import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class Http2PostService { private final RestTemplate http2RestTemplate; public Http2PostService(RestTemplate http2RestTemplate) { this.http2RestTemplate = http2RestTemplate; } public YourResponseDto sendPostRequest(YourRequestDto requestBody) { String fullUrl = "https://your-undertow-service-base-url/your-target-endpoint-path"; return http2RestTemplate.postForObject(fullUrl, requestBody, YourResponseDto.class); } }
- HTTP/2 and HTTPS: Standard HTTP/2 (h2) requires HTTPS. If your Undertow service uses cleartext HTTP/2 (h2c, not recommended for production), adjust your client config to use
HttpProtocol.H2C(for WebClient) or update the Apache HttpClient registry to support h2c. - SSL Certificates: Never use the insecure trust manager in production. Always configure your client to trust the valid SSL certificates issued to your Undertow service.
- Spring Boot Version: Ensure you're using a recent Spring Boot version (2.3+)—older versions have limited HTTP/2 client support.
内容的提问来源于stack exchange,提问作者Peter

