Spring Boot 3中使用RestTemplate发送带请求体的GET请求
Spring Boot 3 发送带请求体的GET请求方案
优先方案:自定义RestTemplate配置
Spring Boot 3 默认使用 HttpClient 5,而 HttpClient 5 会默认禁止 GET 请求携带请求体,因此需要先配置支持该行为的 HttpClient 实例,再注入到 RestTemplate 中。
1. 配置支持GET带请求体的RestTemplate
创建配置类,构建允许GET请求带请求体的HttpClient,并设置为RestTemplate的请求工厂:
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.HttpMethod; import org.apache.hc.core5.http.config.HttpConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { // 构建HttpClient,允许GET请求携带请求体 CloseableHttpClient httpClient = HttpClients.custom() .setDefaultHttpConfig(HttpConfig.custom() .setAllowRequestBodyForHttpMethods(HttpMethod.GET) .build()) .build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(requestFactory); } }
2. 使用RestTemplate发送带请求体的GET请求
注入上述配置的RestTemplate,构造包含请求体的HttpEntity,调用exchange方法发送请求:
import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; // 通过依赖注入获取RestTemplate private final RestTemplate restTemplate; public String sendGetRequestWithBody(String serverUrl, Object requestBody) { // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 构造包含请求体的请求实体 HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers); // 发送GET请求并获取响应 return restTemplate.exchange( serverUrl, HttpMethod.GET, requestEntity, String.class ).getBody(); }
备选方案:直接使用HttpClient 5发送请求
如果不需要RestTemplate的封装,可直接配置HttpClient 5发送带请求体的GET请求:
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpMethod; import org.apache.hc.core5.http.config.HttpConfig; import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.http.io.entity.EntityUtils; public void sendGetWithBodyDirectly() throws Exception { // 构建支持GET带请求体的HttpClient try (CloseableHttpClient httpClient = HttpClients.custom() .setDefaultHttpConfig(HttpConfig.custom() .setAllowRequestBodyForHttpMethods(HttpMethod.GET) .build()) .build()) { HttpGet httpGet = new HttpGet("http://your-server-url"); // 设置请求体 String requestBody = "{\"param1\": \"value1\", \"param2\": \"value2\"}"; StringEntity entity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); httpGet.setEntity(entity); // 执行请求并解析响应 try (var response = httpClient.execute(httpGet)) { String responseBody = EntityUtils.toString(response.getEntity()); // 处理响应内容 System.out.println(responseBody); } } }
关键说明
HttpClient 5 默认会校验HTTP方法与请求体的合法性,通过setAllowRequestBodyForHttpMethods(HttpMethod.GET)可以关闭GET请求的请求体校验,从而支持带请求体的GET请求。
内容的提问来源于stack exchange,提问作者keemahs
相关产品推荐
相关产品推荐

