Replacing OpenFeign with Apache HttpClient, OkHttp, and RestTemplate in Spring Applications
This article explains why and how to replace OpenFeign with native Spring HttpInterface alternatives such as Apache HttpClient, OkHttp, and RestTemplate, covering security motivations, configuration details, code examples, and practical recommendations for microservice remote calls.
In many enterprises the use of OpenFeign is discouraged because it introduces Spring Cloud dependencies that fall outside strict security policies; teams prefer to rely only on core Spring, Apache, or self‑developed libraries and to prepare for Spring 6’s built‑in Http Interface.
The article first introduces OpenFeign, noting that it extends Feign with Spring MVC annotations and uses URLConnection by default. The @FeignClient annotation is described, with its key attributes such as url , name / value , path , configuration , and fallback . A minimal example is provided:
@FeignClient(url = "https://xxx.abcdef.com", name = "SubmitTaskClient", configuration = OpenFeignFormConfig.class, fallback = HystrixFallbackConfig.class)
public interface SubmitTaskClient {
@PostMapping
String submitNormalTask(@RequestBody String paramJsonStr, @RequestHeader Map
header);
@PostMapping(value = "/task/create", headers = {"content-type=application/x-www-form-urlencoded"})
String submitTransTask(Map
map);
}Two typical usage patterns are highlighted: (1) when the remote service is registered in a service registry, the name attribute refers to the registry entry; (2) when calling a standalone HTTP endpoint, the url attribute specifies the target address.
The article then surveys common HTTP client APIs that can replace OpenFeign:
Apache HttpClient
Apache HttpClient is a long‑standing, feature‑rich client. The Maven dependency and a POST helper method are shown:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency> public String apacheHttpClientPost(String url, String params) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/json");
StringEntity entity = new StringEntity(params, "UTF-8");
httpPost.setEntity(entity);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
return EntityUtils.toString(response.getEntity());
}
} finally {
if (response != null) response.close();
httpclient.close();
}
return null;
}OkHttp
OkHttp3 is a modern, efficient client from Square. Its Maven coordinates and a POST method are provided:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency> public String okHttpPostMethod(String url, String body, OkHttpClient okHttpClient) throws IOException {
MediaType JSON_TYPE = MediaType.parse("application/json");
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(JSON_TYPE, body))
.addHeader("Content-Type", "application/json")
.build();
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
return response.body() != null ? response.body().string() : "";
}
return null;
}Hutool
Hutool offers a concise HTTP wrapper based on HttpURLConnection , but the article notes that security policies may forbid its use. The Maven dependency and a generic request helper are shown:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.8</version>
</dependency> public String huToolMethod(String url, HttpMethod httpMethod, RequestBody body) {
Map
headers = new HashMap<>();
headers.put(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8");
HttpRequest request = HttpUtil.createRequest(Method.valueOf(httpMethod.name()), url);
HttpResponse response = request.addHeaders(headers).body(JSON.toJSONString(body)).execute();
return response.body();
}Finally, the article presents Spring's native RestTemplate as a fully supported alternative. After adding the spring-web dependency, a configuration class creates a RestTemplate bean with custom timeouts:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.22</version>
</dependency> @Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(10000);
factory.setReadTimeout(10000);
return factory;
}
}Using RestTemplate.execute() , a flexible method can send any HTTP verb with custom headers and body:
public String restTemplateExecuteMethod(String url, String token, Object body, HttpMethodName method) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", token);
httpHeaders.add("Content-Type", "application/json;charset=utf-8");
HttpEntity
httpEntity = new HttpEntity<>(body, httpHeaders);
RequestCallback requestCallback = restTemplate.httpEntityCallback(httpEntity, Object.class);
ResponseExtractor
> responseExtractor = restTemplate.responseEntityExtractor(Object.class);
ResponseEntity
entity = restTemplate.execute(url, HttpMethod.valueOf(method.name()), requestCallback, responseExtractor);
Assert.notNull(entity, "返回体为空!");
return JSON.toJSONString(entity.getBody());
}The article concludes that, for the author’s scenario, OkHttp3 is preferred for simple POST/GET calls while RestTemplate (or its .execute() method) is better for generic HTTP operations, effectively replacing OpenFeign without introducing prohibited dependencies.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.