0
# HTTP Clients
1
2
Robust HTTP client implementations with factory patterns, request/response utilities, and integration with Apache HttpClient for reliable network communications.
3
4
## HttpClient Interface
5
6
Core interface defining HTTP client behavior with support for various messaging patterns.
7
8
```java { .api }
9
public interface HttpClient {
10
11
// Bean names for different client configurations
12
String BEAN_NAME_HTTPCLIENT_TRUST_STORE = "httpClientTrustStore";
13
String BEAN_NAME_HTTPCLIENT_NO_REDIRECT = "httpClientNoRedirect";
14
String BEAN_NAME_HTTPCLIENT = "httpClient";
15
16
// Core messaging operations
17
boolean sendMessageToEndPoint(HttpMessage message);
18
HttpMessage sendMessageToEndPoint(URL url);
19
20
// Endpoint validation
21
boolean isValidEndPoint(String url);
22
boolean isValidEndPoint(URL url);
23
24
// Access to underlying client
25
org.apache.hc.client5.http.classic.HttpClient wrappedHttpClient();
26
27
// Factory access
28
HttpClientFactory httpClientFactory();
29
}
30
```
31
32
### Usage Examples
33
34
**Basic HTTP operations:**
35
```java
36
@Service
37
public class ExternalApiService {
38
39
private final HttpClient httpClient;
40
41
public ExternalApiService(@Qualifier("httpClient") HttpClient httpClient) {
42
this.httpClient = httpClient;
43
}
44
45
public boolean notifyEndpoint(String endpoint, String payload) {
46
try {
47
URL url = new URL(endpoint);
48
49
// Validate endpoint first
50
if (!httpClient.isValidEndPoint(url)) {
51
log.warn("Invalid endpoint: {}", endpoint);
52
return false;
53
}
54
55
// Create and send message
56
HttpMessage message = new HttpMessage(url, "POST");
57
message.setContentType("application/json");
58
message.setEntity(payload);
59
60
return httpClient.sendMessageToEndPoint(message);
61
62
} catch (Exception e) {
63
log.error("Failed to send notification", e);
64
return false;
65
}
66
}
67
68
public String fetchData(String endpoint) {
69
try {
70
URL url = new URL(endpoint);
71
HttpMessage response = httpClient.sendMessageToEndPoint(url);
72
return response != null ? response.getMessage() : null;
73
} catch (Exception e) {
74
log.error("Failed to fetch data from {}", endpoint, e);
75
return null;
76
}
77
}
78
}
79
```
80
81
## SimpleHttpClient
82
83
Simple HTTP client implementation providing basic HTTP operations with reasonable defaults.
84
85
```java { .api }
86
public class SimpleHttpClient implements HttpClient {
87
88
// Constructors
89
public SimpleHttpClient();
90
public SimpleHttpClient(HttpClientFactory httpClientFactory);
91
92
// HttpClient interface implementation
93
@Override
94
public boolean sendMessageToEndPoint(HttpMessage message);
95
96
@Override
97
public HttpMessage sendMessageToEndPoint(URL url);
98
99
@Override
100
public boolean isValidEndPoint(String url);
101
102
@Override
103
public boolean isValidEndPoint(URL url);
104
105
@Override
106
public org.apache.hc.client5.http.classic.HttpClient wrappedHttpClient();
107
108
@Override
109
public HttpClientFactory httpClientFactory();
110
}
111
```
112
113
### Usage Examples
114
115
**Simple HTTP client configuration:**
116
```java
117
@Configuration
118
public class HttpClientConfiguration {
119
120
@Bean
121
@Primary
122
public HttpClient defaultHttpClient() {
123
return new SimpleHttpClient();
124
}
125
126
@Bean("httpClientNoRedirect")
127
public HttpClient noRedirectHttpClient() {
128
HttpClientFactory factory = createNoRedirectFactory();
129
return new SimpleHttpClient(factory);
130
}
131
132
private HttpClientFactory createNoRedirectFactory() {
133
return new SimpleHttpClientFactory() {
134
@Override
135
public org.apache.hc.client5.http.classic.HttpClient getHttpClient() {
136
return HttpClients.custom()
137
.disableRedirectHandling()
138
.build();
139
}
140
};
141
}
142
}
143
```
144
145
## SimpleHttpClientFactoryBean
146
147
Spring factory bean for creating and configuring HTTP clients in application contexts.
148
149
```java { .api }
150
public class SimpleHttpClientFactoryBean implements FactoryBean<HttpClient>,
151
InitializingBean,
152
DisposableBean {
153
154
// Configuration properties
155
public void setConnectionTimeout(int connectionTimeout);
156
public void setReadTimeout(int readTimeout);
157
public void setMaxTotalConnections(int maxTotalConnections);
158
public void setMaxConnectionsPerRoute(int maxConnectionsPerRoute);
159
160
// SSL configuration
161
public void setTrustManagerFactory(TrustManagerFactory trustManagerFactory);
162
public void setSslContext(SSLContext sslContext);
163
public void setHostnameVerifier(HostnameVerifier hostnameVerifier);
164
165
// Proxy configuration
166
public void setProxyHost(String proxyHost);
167
public void setProxyPort(int proxyPort);
168
public void setProxyCredentials(Credentials proxyCredentials);
169
170
// FactoryBean implementation
171
@Override
172
public HttpClient getObject() throws Exception;
173
174
@Override
175
public Class<?> getObjectType();
176
177
@Override
178
public boolean isSingleton();
179
180
// Lifecycle methods
181
@Override
182
public void afterPropertiesSet() throws Exception;
183
184
@Override
185
public void destroy() throws Exception;
186
}
187
```
188
189
### Usage Examples
190
191
**Spring configuration with factory bean:**
192
```java
193
@Configuration
194
public class HttpClientConfiguration {
195
196
@Bean
197
public SimpleHttpClientFactoryBean httpClientFactory() {
198
SimpleHttpClientFactoryBean factory = new SimpleHttpClientFactoryBean();
199
200
// Connection settings
201
factory.setConnectionTimeout(30000); // 30 seconds
202
factory.setReadTimeout(60000); // 60 seconds
203
factory.setMaxTotalConnections(100);
204
factory.setMaxConnectionsPerRoute(20);
205
206
// Proxy settings if needed
207
factory.setProxyHost("proxy.example.com");
208
factory.setProxyPort(8080);
209
210
return factory;
211
}
212
213
@Bean
214
public HttpClient httpClient(SimpleHttpClientFactoryBean factory) throws Exception {
215
return factory.getObject();
216
}
217
}
218
```
219
220
**SSL configuration:**
221
```java
222
@Configuration
223
public class SecureHttpClientConfiguration {
224
225
@Bean
226
public SimpleHttpClientFactoryBean secureHttpClientFactory() throws Exception {
227
SimpleHttpClientFactoryBean factory = new SimpleHttpClientFactoryBean();
228
229
// SSL configuration
230
SSLContext sslContext = createCustomSSLContext();
231
factory.setSslContext(sslContext);
232
factory.setHostnameVerifier(NoopHostnameVerifier.INSTANCE);
233
234
return factory;
235
}
236
237
private SSLContext createCustomSSLContext() throws Exception {
238
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
239
KeyStore trustStore = loadTrustStore();
240
tmf.init(trustStore);
241
242
SSLContext sslContext = SSLContext.getInstance("TLS");
243
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
244
return sslContext;
245
}
246
}
247
```
248
249
## HttpClientFactory Interface
250
251
Factory interface for creating HTTP client instances with customizable configurations.
252
253
```java { .api }
254
public interface HttpClientFactory {
255
256
// Core factory method
257
org.apache.hc.client5.http.classic.HttpClient getHttpClient();
258
259
// Configuration methods
260
void configure(HttpClientBuilder builder);
261
void configureConnectionManager(PoolingHttpClientConnectionManager connectionManager);
262
void configureRequestConfig(RequestConfig.Builder requestConfigBuilder);
263
}
264
```
265
266
## HttpExecutionRequest
267
268
Wrapper class for HTTP execution requests providing additional context and configuration.
269
270
```java { .api }
271
public class HttpExecutionRequest {
272
273
// Request properties
274
private final HttpUriRequest request;
275
private final HttpContext context;
276
private final ResponseHandler<String> responseHandler;
277
278
// Constructor
279
public HttpExecutionRequest(HttpUriRequest request);
280
public HttpExecutionRequest(HttpUriRequest request, HttpContext context);
281
public HttpExecutionRequest(HttpUriRequest request,
282
HttpContext context,
283
ResponseHandler<String> responseHandler);
284
285
// Getters
286
public HttpUriRequest getRequest();
287
public HttpContext getContext();
288
public ResponseHandler<String> getResponseHandler();
289
}
290
```
291
292
### Usage Examples
293
294
**Custom HTTP execution:**
295
```java
296
@Service
297
public class AdvancedHttpService {
298
299
private final HttpClient httpClient;
300
301
public String executeRequest(String url, Map<String, String> headers) {
302
try {
303
// Create request
304
HttpGet request = new HttpGet(url);
305
headers.forEach(request::setHeader);
306
307
// Create context
308
HttpContext context = new BasicHttpContext();
309
context.setAttribute(HttpClientContext.REQUEST_CONFIG,
310
RequestConfig.custom()
311
.setSocketTimeout(30000)
312
.setConnectTimeout(10000)
313
.build());
314
315
// Custom response handler
316
ResponseHandler<String> handler = response -> {
317
int status = response.getStatusLine().getStatusCode();
318
if (status >= 200 && status < 300) {
319
return EntityUtils.toString(response.getEntity());
320
} else {
321
throw new ClientProtocolException("Unexpected response status: " + status);
322
}
323
};
324
325
// Execute with wrapper
326
HttpExecutionRequest execRequest = new HttpExecutionRequest(request, context, handler);
327
return executeHttpRequest(execRequest);
328
329
} catch (Exception e) {
330
log.error("Failed to execute HTTP request", e);
331
throw new RuntimeException("HTTP request failed", e);
332
}
333
}
334
335
private String executeHttpRequest(HttpExecutionRequest execRequest) throws Exception {
336
org.apache.hc.client5.http.classic.HttpClient client = httpClient.wrappedHttpClient();
337
return client.execute(execRequest.getRequest(),
338
execRequest.getContext(),
339
execRequest.getResponseHandler());
340
}
341
}
342
```
343
344
## HttpRequestUtils
345
346
Utility methods for HTTP request processing and manipulation.
347
348
```java { .api }
349
@UtilityClass
350
public class HttpRequestUtils {
351
352
// Request extraction utilities
353
public static String getRequestParameter(HttpServletRequest request, String name);
354
public static String getRequestParameter(HttpServletRequest request, String name, String defaultValue);
355
356
// Header utilities
357
public static String getRequestHeader(HttpServletRequest request, String name);
358
public static Map<String, String> getRequestHeaders(HttpServletRequest request);
359
360
// URL utilities
361
public static String getFullRequestURL(HttpServletRequest request);
362
public static String getRequestURL(HttpServletRequest request, boolean includeQueryString);
363
364
// Client information
365
public static String getClientIpAddress(HttpServletRequest request);
366
public static String getUserAgent(HttpServletRequest request);
367
368
// Request validation
369
public static boolean isAjaxRequest(HttpServletRequest request);
370
public static boolean isMultipartRequest(HttpServletRequest request);
371
}
372
```
373
374
### Usage Examples
375
376
**HTTP request utilities:**
377
```java
378
@RestController
379
public class ApiController {
380
381
@PostMapping("/api/data")
382
public ResponseEntity<?> handleRequest(HttpServletRequest request) {
383
384
// Extract request information
385
String clientIp = HttpRequestUtils.getClientIpAddress(request);
386
String userAgent = HttpRequestUtils.getUserAgent(request);
387
String fullUrl = HttpRequestUtils.getFullRequestURL(request);
388
389
// Get parameters with defaults
390
String format = HttpRequestUtils.getRequestParameter(request, "format", "json");
391
392
// Check request type
393
boolean isAjax = HttpRequestUtils.isAjaxRequest(request);
394
boolean isMultipart = HttpRequestUtils.isMultipartRequest(request);
395
396
// Process based on request characteristics
397
if (isAjax) {
398
return handleAjaxRequest(request);
399
} else if (isMultipart) {
400
return handleMultipartRequest(request);
401
}
402
403
return handleStandardRequest(request);
404
}
405
406
@GetMapping("/api/info")
407
public Map<String, Object> getRequestInfo(HttpServletRequest request) {
408
return Map.of(
409
"clientIp", HttpRequestUtils.getClientIpAddress(request),
410
"userAgent", HttpRequestUtils.getUserAgent(request),
411
"fullUrl", HttpRequestUtils.getFullRequestURL(request),
412
"headers", HttpRequestUtils.getRequestHeaders(request),
413
"isAjax", HttpRequestUtils.isAjaxRequest(request)
414
);
415
}
416
}
417
```
418
419
## HttpUtils
420
421
General HTTP utilities for common HTTP operations and validations.
422
423
```java { .api }
424
@UtilityClass
425
public class HttpUtils {
426
427
// URL validation and manipulation
428
public static boolean isValidHttpUrl(String url);
429
public static URL createURL(String url);
430
public static URI createURI(String uri);
431
432
// Content type utilities
433
public static boolean isJsonContentType(String contentType);
434
public static boolean isXmlContentType(String contentType);
435
public static boolean isFormContentType(String contentType);
436
437
// Response utilities
438
public static void setNoCacheHeaders(HttpServletResponse response);
439
public static void setCorsHeaders(HttpServletResponse response);
440
public static void setContentType(HttpServletResponse response, String contentType);
441
442
// Status code utilities
443
public static boolean isSuccessfulStatus(int statusCode);
444
public static boolean isRedirectStatus(int statusCode);
445
public static boolean isErrorStatus(int statusCode);
446
}
447
```
448
449
### Usage Examples
450
451
**HTTP utilities in action:**
452
```java
453
@Component
454
public class HttpUtilityService {
455
456
public boolean validateAndProcessUrl(String urlString) {
457
// Validate URL
458
if (!HttpUtils.isValidHttpUrl(urlString)) {
459
log.warn("Invalid URL provided: {}", urlString);
460
return false;
461
}
462
463
try {
464
URL url = HttpUtils.createURL(urlString);
465
return processValidUrl(url);
466
} catch (Exception e) {
467
log.error("Failed to create URL", e);
468
return false;
469
}
470
}
471
472
public void configureResponse(HttpServletResponse response, String content, String format) {
473
// Set appropriate content type
474
if ("json".equalsIgnoreCase(format)) {
475
HttpUtils.setContentType(response, "application/json");
476
} else if ("xml".equalsIgnoreCase(format)) {
477
HttpUtils.setContentType(response, "application/xml");
478
}
479
480
// Configure caching and CORS
481
HttpUtils.setNoCacheHeaders(response);
482
HttpUtils.setCorsHeaders(response);
483
484
// Write response
485
try {
486
response.getWriter().write(content);
487
} catch (IOException e) {
488
log.error("Failed to write response", e);
489
}
490
}
491
492
public void handleHttpStatus(int statusCode, String operation) {
493
if (HttpUtils.isSuccessfulStatus(statusCode)) {
494
log.info("Operation {} completed successfully: {}", operation, statusCode);
495
} else if (HttpUtils.isRedirectStatus(statusCode)) {
496
log.info("Operation {} resulted in redirect: {}", operation, statusCode);
497
} else if (HttpUtils.isErrorStatus(statusCode)) {
498
log.error("Operation {} failed with status: {}", operation, statusCode);
499
throw new HttpStatusException(statusCode, "HTTP operation failed");
500
}
501
}
502
}
503
```
504
505
## Integration Examples
506
507
### Complete HTTP Service Implementation
508
509
```java
510
@Service
511
@Slf4j
512
public class ExternalServiceClient {
513
514
private final HttpClient httpClient;
515
private final ObjectMapper objectMapper;
516
517
public ExternalServiceClient(HttpClient httpClient, ObjectMapper objectMapper) {
518
this.httpClient = httpClient;
519
this.objectMapper = objectMapper;
520
}
521
522
public <T> T get(String url, Class<T> responseType) {
523
// Validate endpoint
524
if (!httpClient.isValidEndPoint(url)) {
525
throw new IllegalArgumentException("Invalid endpoint: " + url);
526
}
527
528
try {
529
// Send GET request
530
HttpMessage response = httpClient.sendMessageToEndPoint(new URL(url));
531
532
if (response != null && response.getMessage() != null) {
533
return objectMapper.readValue(response.getMessage(), responseType);
534
}
535
536
return null;
537
538
} catch (Exception e) {
539
log.error("GET request failed for URL: {}", url, e);
540
throw new RuntimeException("HTTP GET failed", e);
541
}
542
}
543
544
public <T> boolean post(String url, T request) {
545
try {
546
// Validate endpoint
547
if (!HttpUtils.isValidHttpUrl(url)) {
548
log.warn("Invalid URL: {}", url);
549
return false;
550
}
551
552
// Create message
553
HttpMessage message = new HttpMessage(new URL(url), "POST");
554
message.setContentType("application/json");
555
556
// Serialize request body
557
String json = objectMapper.writeValueAsString(request);
558
message.setEntity(json);
559
560
// Send request
561
return httpClient.sendMessageToEndPoint(message);
562
563
} catch (Exception e) {
564
log.error("POST request failed for URL: {}", url, e);
565
return false;
566
}
567
}
568
569
public boolean ping(String url) {
570
return httpClient.isValidEndPoint(url);
571
}
572
}
573
```
574
575
This HTTP client library provides a comprehensive foundation for HTTP communications in CAS applications, with support for various configuration patterns, SSL/TLS, proxies, and integration with Spring Framework.