Backend Development 11 min read

Three Ways to Call External APIs in Spring Boot: HttpClient, RestTemplate, and Feign

This article demonstrates three methods for invoking external services in Spring Boot applications—using raw HttpClient, the RestTemplate utility, and Feign clients—providing code examples, configuration steps, and usage details for each approach in production.

Architect's Guide
Architect's Guide
Architect's Guide
Three Ways to Call External APIs in Spring Boot: HttpClient, RestTemplate, and Feign

1. Introduction

SpringBoot inherits Spring's excellent features and further simplifies configuration, making the construction and development of Spring applications easier. In Spring‑Boot projects, you often need to access external module interfaces or URLs, such as invoking APAAS interfaces (e.g., a workflow submit API). This article presents three ways (without Dubbo) to achieve this.

2. Method 1: Using raw HttpClient

/*
 * @description get方式获取入参,插入数据并发起流程
 * @author lyx
 * @date 2022/8/24 16:05
 * @params documentId
 * @return String
 */
@RequestMapping("/submit/{documentId}")
public String submit1(@PathVariable String documentId) throws ParseException {
    //此处将要发送的数据转换为json格式字符串
    Map
map = task2Service.getMap(documentId);
    String jsonStr = JSON.toJSONString(map, SerializerFeature.WRITE_MAP_NULL_FEATURES, SerializerFeature.QuoteFieldNames);
    JSONObject jsonObject = JSON.parseObject(jsonStr);
    JSONObject sr = task2Service.doPost(jsonObject);
    return sr.toString();
}
/*
 * @description 使用原生httpClient调用外部接口
 * @author lyx
 * @date 2022/8/24 16:08
 * @params date
 * @return JSONObject
 */
public static JSONObject doPost(JSONObject date) {
    String assessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9...";
    CloseableHttpClient client = HttpClients.createDefault();
    // 要调用的接口url
    String url = "http://39.103.201.110:30661 /xdap-open/open/process/v1/submit";
    HttpPost post = new HttpPost(url);
    JSONObject jsonObject = null;
    try {
        //创建请求体并添加数据
        StringEntity s = new StringEntity(date.toString());
        //此处相当于在header里头添加content-type等参数
        s.setContentType("application/json");
        s.setContentEncoding("UTF-8");
        post.setEntity(s);
        //此处相当于在Authorization里头添加Bear token参数信息
        post.addHeader("Authorization", "Bearer " + assessToken);
        HttpResponse res = client.execute(post);
        String response1 = EntityUtils.toString(res.getEntity());
        if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 返回json格式:
            String result = EntityUtils.toString(res.getEntity());
            jsonObject = JSONObject.parseObject(result);
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return jsonObject;
}

3. Method 2: Using RestTemplate

Spring‑Boot provides RestTemplate for external API calls. The article introduces GET and POST methods.

GET Requests

Two primary methods are getForObject and getForEntity . The getForEntity overloads include:

1.getForEntity(String url, Class responseType, Object… urlVariables)
2.getForEntity(URI url, Class responseType)

Get--getForEntity(URI url, Class responseType)

// Using URI to specify address and parameters
RestTemplate restTemplate = new RestTemplate();
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://USER-SERVICE/user?name={name}")
    .build()
    .expand("dodo")
    .encode();
URI uri = uriComponents.toUri();
ResponseEntity
responseEntity = restTemplate.getForEntity(uri, String.class);

Get--getForEntity(String url, Class responseType, Object… urlVariables)

// Example with URL variables
RestTemplate restTemplate = new RestTemplate();
Map
params = new HashMap<>();
params.put("name", "dada");
ResponseEntity
responseEntity = restTemplate.getForEntity(
    "http://USER-SERVICE/user?name={name}", String.class, params);

GET with getForObject has three overloads similar to getForEntity , and it internally uses HttpMessageConverterExtractor to convert the response body into the desired object.

POST Requests

POST methods include postForEntity , postForObject , and postForLocation . The article demonstrates postForEntity (second overload) as follows:

/*
 * @description post方式获取入参,插入数据并发起流程
 */
@PostMapping("/submit2")
public Object insertFinanceCompensation(@RequestBody JSONObject jsonObject) {
    String documentId = jsonObject.get("documentId").toString();
    return task2Service.submit(documentId);
}
/*
 * @description 使用RestTemplate调外部接口
 */
public String submit(String documentId) {
    String assessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9...";
    RestTemplate restTemplate = new RestTemplate();
    //创建请求头
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add(HttpHeaders.AUTHORIZATION, "Bearer " + assessToken);
    httpHeaders.add(HttpHeaders.CONTENT_TYPE, "application/json");
    Map
map = getMap(documentId);
    String jsonStr = JSON.toJSONString(map);
    HttpEntity
httpEntity = new HttpEntity<>(map, httpHeaders);
    String url = "http://39.103.201.110:30661/xdap-open/open/process/v1/submit";
    ResponseEntity
forEntity = restTemplate.postForEntity(url, httpEntity, String.class);
    return forEntity.toString();
}

4. Method 3: Using Feign

Add the Maven dependency:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.2.2.RELEASE</version>
</dependency>

Enable Feign in the main class with @EnableFeignClients and define the application entry:

@SpringBootApplication
@EnableFeignClients
@ComponentScan(basePackages = {"com.definesys.mpaas", "com.xdap.*"})
public class MobilecardApplication {
    public static void main(String[] args) {
        SpringApplication.run(MobilecardApplication.class, args);
    }
}

Define a mock external controller:

@Autowired
PrintService printService;

@PostMapping("/outSide")
public String test(@RequestBody TestDto testDto) {
    return printService.print(testDto);
}

Define the service interface and implementation:

@Service
public interface PrintService {
    public String print(TestDto testDto);
}
public class PrintServiceImpl implements PrintService {
    @Override
    public String print(TestDto testDto) {
        return "模拟外部系统的接口功能" + testDto.getId();
    }
}

Feign client definition (URL configured in application.properties ) and token header interceptor:

// Feign client interface
@FeignClient(url = "${outSide.url}", name = "service2")
public interface FeignService2 {
    @RequestMapping(value = "/custom/outSide", method = RequestMethod.POST)
    @ResponseBody
    public String getMessage(@Valid @RequestBody TestDto testDto);
}
// Request interceptor to add token header
@Configuration
public class FeignConfig implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9...");
    }
}

Controller that uses the Feign client (with token):

@PostMapping("/testToken")
public String test4(@RequestBody TestDto testDto) {
    return tokenDemoClient.getMessage(testDto);
}

Testing can be performed with Postman, ensuring the required headers (Authorization, Content-Type, token) are included.

Additional Promotional Content

The article ends with a call to follow the author's public account, offering additional resources such as "How to design a secure external interface?", "SpringBoot API anti‑scraping", and "Comprehensive guide to OAuth2.0".

feignSpringBootRestTemplateAPI IntegrationHttpClient
Architect's Guide
Written by

Architect's Guide

Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.