Spring Boot中如何通过GET请求体向外部API发送JSON数据
在Spring Boot中通过GET请求携带请求体调用外部API
注意事项
首先明确:HTTP规范中并未禁止GET请求携带请求体,但绝大多数HTTP服务器和客户端框架对这种方式的支持并不完善,很多外部API可能直接拒绝带请求体的GET请求。如果可以的话,优先使用POST请求发送JSON数据,更符合规范且兼容性更好。
如果必须使用GET请求带请求体,以下是两种常见实现方式:
方式一:使用RestTemplate
RestTemplate默认不支持GET请求带请求体,需要自定义请求工厂实现:
- 自定义请求工厂类
import org.springframework.http.client.SimpleClientHttpRequestFactory; import java.io.IOException; import java.net.HttpURLConnection; public class GetWithBodyRequestFactory extends SimpleClientHttpRequestFactory { @Override protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { super.prepareConnection(connection, httpMethod); // 允许GET请求携带请求体 if ("GET".equals(httpMethod)) { connection.setDoOutput(true); connection.setRequestMethod("GET"); } } }
- 配置RestTemplate Bean
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(new GetWithBodyRequestFactory()); } }
- 发送请求
import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; public class ApiService { @Resource private RestTemplate restTemplate; public String callExternalApi() { // 构造请求体 String requestBody = "{\n" + "\"key1\" : \"value1\",\n" + "\"key2\" : \"value2\",\n" + "\"key3\" : \"value3\"\n" + "}"; // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers); // 替换为实际的外部API地址 String url = "https://external-api-url.com/endpoint"; return restTemplate.exchange(url, org.springframework.http.HttpMethod.GET, requestEntity, String.class).getBody(); } }
方式二:使用WebClient(Spring 5+推荐)
WebClient对GET请求带请求体的支持更友好,无需额外配置:
- 配置WebClient Bean
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.WebClient; @Configuration public class WebClientConfig { @Bean public WebClient webClient() { return WebClient.builder().build(); } }
- 发送请求
import org.springframework.http.MediaType; import org.springframework.web.reactive.function.client.WebClient; import javax.annotation.Resource; import reactor.core.publisher.Mono; public class ReactiveApiService { @Resource private WebClient webClient; public Mono<String> callExternalApi() { // 构造请求体,也可使用Map或自定义实体类 String requestBody = "{\n" + "\"key1\" : \"value1\",\n" + "\"key2\" : \"value2\",\n" + "\"key3\" : \"value3\"\n" + "}"; return webClient.get() .uri("https://external-api-url.com/endpoint") .contentType(MediaType.APPLICATION_JSON) .bodyValue(requestBody) .retrieve() .bodyToMono(String.class); } }
额外提醒
- 务必确认外部API确实支持接收带请求体的GET请求,否则会返回4xx错误。
- 如果外部API仅要求用POST方法接收JSON,直接使用POST请求调用即可,代码更简单且符合规范,比如RestTemplate的
postForObject方法,或WebClient的post()方法。
内容的提问来源于stack exchange,提问作者Khaski
相关产品推荐
相关产品推荐

