1. RestTemplate Bean Configuration
The basic configuration creates a RestTemplate instance as a Spring bean:
@Configuration
public class RestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
For environments using self-signed certificates (such as development or testing), you can configure RestTemplate to skip SSL verification:
@Bean
public RestTemplate restTemplate() throws Exception {
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}
2. HTTP Utility Class Implementation
Creating a dedicated utility component centralizes HTTP handling logic, improves code reusability, and provides consistent exception handling across your application.
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
/**
* HTTP request utility component
*/
@Component
public class HttpClientHelper {
private static final Logger log = LoggerFactory.getLogger(HttpClientHelper.class);
@Autowired
private RestTemplate httpClient;
/**
* Execute GET request with custom headers
*/
public String executeGet(String endpoint, Map<String, String> requestHeaders) {
HttpHeaders headers = new HttpHeaders();
if (requestHeaders != null) {
requestHeaders.forEach(headers::add);
}
HttpEntity<String> request = new HttpEntity<>(headers);
try {
ResponseEntity<String> response = httpClient.exchange(
endpoint, HttpMethod.GET, request, String.class);
return response.getBody();
} catch (HttpStatusCodeException ex) {
log.error("GET request failed with status {} to {}: {}",
ex.getStatusCode(), endpoint, ex.getResponseBodyAsString());
throw ex;
} catch (RestClientException ex) {
log.error("Connection error during GET request to {}: {}",
endpoint, ex.getMessage());
throw ex;
}
}
/**
* Execute POST request with JSON body
*/
public String executePost(String endpoint, Map<String, Object> payload,
Map<String, String> requestHeaders) {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json;charset=UTF-8");
if (requestHeaders != null) {
requestHeaders.forEach(headers::add);
}
String jsonBody = convertToJson(payload);
HttpEntity<String> request = new HttpEntity<>(jsonBody, headers);
try {
ResponseEntity<String> response = httpClient.exchange(
endpoint, HttpMethod.POST, request, String.class);
return response.getBody();
} catch (HttpStatusCodeException ex) {
log.error("POST request failed with status {} to {}: {}",
ex.getStatusCode(), endpoint, ex.getResponseBodyAsString());
throw ex;
} catch (RestClientException ex) {
log.error("Connection error during POST request to {}: {}",
endpoint, ex.getMessage());
throw ex;
}
}
private static String convertToJson(Map<String, Object> data) {
return JSON.toJSONString(data);
}
}
3. Service Integration Example
Inject the utility into your service layer for clean, readable API calls:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class ExternalApiService {
@Autowired
private HttpClientHelper httpHelper;
public void callExternalEndpoints() {
String fetchEndpoint = "https://api.example.com/resource";
String submitEndpoint = "https://api.example.com/submit";
Map<String, Object> payload = new HashMap<>();
payload.put("username", "admin");
payload.put("age", 25);
// GET request example
String fetchResult = httpHelper.executeGet(fetchEndpoint, null);
System.out.println("GET Result: " + fetchResult);
// POST request example
Map<String, String> authHeaders = new HashMap<>();
authHeaders.put("Authorization", "Bearer token123");
String submitResult = httpHelper.executePost(submitEndpoint, payload, authHeaders);
System.out.println("POST Result: " + submitResult);
}
}
4. Frequently Asked Questions
- Is RestTemplate thread-safe? Yes, RestTemplate instances are thread-safe when used as singletons. Inject a single bean instance across your application.
- How to handle HTTPS certificate errors? Configure
NoopHostnameVerifierandTrustSelfSignedStrategyin the SSL context (shown in section 1). Only use this in non-production environmetns. - How to add PUT and DELETE support? Extend the utility class with similar methods using
HttpMethod.PUTandHttpMethod.DELETEflolowing the same pattern.