Setting Up the HTTP Client
A customized RestTemplate bean provides fine-graineed control over connection behavior. The configuration below binds a request factory with a timeout setting.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class HttpClientConfig {
@Bean
public SimpleClientHttpRequestFactory requestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(1000);
factory.setReadTimeout(3000);
return factory;
}
@Bean
public RestTemplate restTemplate(SimpleClientHttpRequestFactory requestFactory) {
return new RestTemplate(requestFactory);
}
}
Sample Server-Side Controller
Asssume a service exposes a collection of resources at /orders. The hendler produces a plain JSON array.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class OrderController {
@GetMapping(value = "/orders", produces = "application/json")
public List<Order> fetchOrders() {
List<Order> result = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Order item = new Order();
item.setId(i);
item.setLabel(String.format("Order-%d", i));
result.add(item);
}
return result;
}
}
Deserializing the Response
Strategy 1 — Target a Plain Array
Map the response body directly to a Java array, then wrap it in a List.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
@Component
public class ArrayBasedConsumer {
private static final String BASE_URL = "http://localhost:8080/api/";
@Autowired
private RestTemplate restTemplate;
public List<Order> loadAllOrders() {
Order[] rawArray = restTemplate.getForObject(
BASE_URL + "orders", Order[].class
);
return Arrays.asList(rawArray);
}
}
Strategy 2 — Exploit ParameterizedTypeReference
Use exchange with a ParameterizedTypeReference to capture the generic list type directly, avoiding the intermediate array step.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Component
public class GenericTypeConsumer {
private static final String ENDPOINT = "http://localhost:8080/api/orders";
@Autowired
private RestTemplate restTemplate;
public List<Order> retrieveOrders() {
ParameterizedTypeReference<List<Order>> typeRef = new ParameterizedTypeReference<>() {};
ResponseEntity<List<Order>> response = restTemplate.exchange(
ENDPOINT,
HttpMethod.GET,
null,
typeRef
);
return response.getBody();
}
}
Both approaches yield the same result: the full list of Order objects returned by the service. The choice depends on personal preference and whether you need access to response headers or status codes.