or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdclient-config.mdconnectors-spi.mdfilters-features.mdindex.mdrequest-execution.md

connectors-spi.mddocs/

0

# Connectors and SPI

1

2

Service Provider Interface for pluggable HTTP transport connectors and extensibility hooks including custom connectors, request/response interceptors, client lifecycle listeners, and async callback mechanisms. This functionality enables deep customization and integration with different HTTP client implementations.

3

4

## Capabilities

5

6

### Connector Provider Interface

7

8

Core interface for providing HTTP transport connectors that handle the actual HTTP communication.

9

10

```java { .api }

11

/**

12

* Contract for providing client transport connectors

13

*/

14

public interface ConnectorProvider {

15

/**

16

* Create connector instance for the given client and configuration

17

* @param client client instance requesting the connector

18

* @param runtimeConfig runtime configuration for the connector

19

* @return configured connector instance

20

*/

21

Connector getConnector(Client client, Configuration runtimeConfig);

22

}

23

```

24

25

### Connector Interface

26

27

Core connector interface that handles HTTP request execution with support for both synchronous and asynchronous operations.

28

29

```java { .api }

30

/**

31

* Client transport connector for executing HTTP requests

32

*/

33

public interface Connector extends Inflector<ClientRequest, ClientResponse> {

34

/**

35

* Execute HTTP request synchronously

36

* @param request client request to execute

37

* @return client response

38

*/

39

ClientResponse apply(ClientRequest request);

40

41

/**

42

* Execute HTTP request asynchronously

43

* @param request client request to execute

44

* @param callback callback for handling response or failure

45

* @return Future representing the async operation

46

*/

47

Future<?> apply(ClientRequest request, AsyncConnectorCallback callback);

48

49

/**

50

* Get connector name for identification

51

* @return connector name

52

*/

53

String getName();

54

55

/**

56

* Close connector and release resources

57

*/

58

void close();

59

}

60

```

61

62

### Async Connector Callback

63

64

Callback interface for handling asynchronous HTTP request results and failures.

65

66

```java { .api }

67

/**

68

* Callback interface for asynchronous connector operations

69

*/

70

public interface AsyncConnectorCallback {

71

/**

72

* Handle successful response

73

* @param response client response from successful request

74

*/

75

void response(ClientResponse response);

76

77

/**

78

* Handle request failure

79

* @param failure throwable representing the failure cause

80

*/

81

void failure(Throwable failure);

82

}

83

```

84

85

### HTTP URL Connector Provider

86

87

Default connector provider implementation using Java's built-in HttpURLConnection for HTTP transport.

88

89

```java { .api }

90

public class HttpUrlConnectorProvider implements ConnectorProvider {

91

// Configuration properties

92

public static final String USE_FIXED_LENGTH_STREAMING = "jersey.config.client.httpUrlConnector.useFixedLengthStreaming";

93

public static final String SET_METHOD_WORKAROUND = "jersey.config.client.httpUrlConnector.setMethodWorkaround";

94

95

/**

96

* Create default HTTP URL connector provider

97

*/

98

public HttpUrlConnectorProvider();

99

100

/**

101

* Configure connector with custom connection factory

102

* @param connectionFactory factory for creating HTTP connections

103

* @return configured connector provider

104

*/

105

public HttpUrlConnectorProvider connectionFactory(ConnectionFactory connectionFactory);

106

107

/**

108

* Configure chunk size for chunked encoding

109

* @param chunkSize chunk size in bytes

110

* @return configured connector provider

111

*/

112

public HttpUrlConnectorProvider chunkSize(int chunkSize);

113

114

/**

115

* Enable fixed-length streaming mode

116

* @return configured connector provider

117

*/

118

public HttpUrlConnectorProvider useFixedLengthStreaming();

119

120

/**

121

* Enable HTTP method workaround for restricted methods

122

* @return configured connector provider

123

*/

124

public HttpUrlConnectorProvider useSetMethodWorkaround();

125

126

/**

127

* Create connector instance

128

* @param client client instance

129

* @param config runtime configuration

130

* @return HTTP URL connector instance

131

*/

132

public Connector getConnector(Client client, Configuration config);

133

}

134

```

135

136

### Connection Factory

137

138

Factory interface for creating HTTP URL connections with optional proxy support.

139

140

```java { .api }

141

/**

142

* Factory for creating HTTP URL connections

143

*/

144

public interface ConnectionFactory {

145

/**

146

* Create HTTP connection for the given URL

147

* @param url target URL for connection

148

* @return HTTP URL connection

149

* @throws IOException if connection creation fails

150

*/

151

HttpURLConnection getConnection(URL url) throws IOException;

152

153

/**

154

* Create HTTP connection for the given URL with proxy

155

* @param url target URL for connection

156

* @param proxy proxy for connection

157

* @return HTTP URL connection

158

* @throws IOException if connection creation fails

159

*/

160

default HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {

161

return getConnection(url);

162

}

163

}

164

```

165

166

**Usage Examples:**

167

168

```java

169

import org.glassfish.jersey.client.HttpUrlConnectorProvider;

170

import java.net.HttpURLConnection;

171

import java.net.URL;

172

import java.net.Proxy;

173

174

// Custom connection factory

175

HttpUrlConnectorProvider.ConnectionFactory customFactory = new HttpUrlConnectorProvider.ConnectionFactory() {

176

@Override

177

public HttpURLConnection getConnection(URL url) throws IOException {

178

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

179

connection.setConnectTimeout(10000);

180

connection.setReadTimeout(30000);

181

return connection;

182

}

183

184

@Override

185

public HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {

186

HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);

187

connection.setConnectTimeout(10000);

188

connection.setReadTimeout(30000);

189

return connection;

190

}

191

};

192

193

// Configure client with custom connector

194

HttpUrlConnectorProvider connectorProvider = new HttpUrlConnectorProvider()

195

.connectionFactory(customFactory)

196

.chunkSize(8192)

197

.useFixedLengthStreaming();

198

199

ClientConfig config = new ClientConfig();

200

config.connectorProvider(connectorProvider);

201

Client client = JerseyClientBuilder.createClient(config);

202

```

203

204

### Caching Connector Provider

205

206

Caching wrapper for connector providers that reuses connector instances for improved performance.

207

208

```java { .api }

209

public class CachingConnectorProvider implements ConnectorProvider {

210

/**

211

* Create caching wrapper for the given connector provider

212

* @param delegate underlying connector provider to cache

213

*/

214

public CachingConnectorProvider(ConnectorProvider delegate);

215

216

/**

217

* Get connector instance (cached if previously created)

218

* @param client client instance

219

* @param runtimeConfig runtime configuration

220

* @return cached or new connector instance

221

*/

222

public Connector getConnector(Client client, Configuration runtimeConfig);

223

}

224

```

225

226

**Usage Examples:**

227

228

```java

229

// Wrap any connector provider with caching

230

ConnectorProvider baseProvider = new HttpUrlConnectorProvider();

231

ConnectorProvider cachingProvider = new CachingConnectorProvider(baseProvider);

232

233

ClientConfig config = new ClientConfig();

234

config.connectorProvider(cachingProvider);

235

Client client = JerseyClientBuilder.createClient(config);

236

```

237

238

### Client Builder Listener

239

240

Listener interface for intercepting client builder creation events.

241

242

```java { .api }

243

/**

244

* Listener for client builder creation events

245

*/

246

public interface ClientBuilderListener {

247

/**

248

* Called when a new client builder is created

249

* @param builder newly created client builder

250

*/

251

void onNewBuilder(ClientBuilder builder);

252

}

253

```

254

255

### Invocation Builder Listener

256

257

Listener interface for intercepting invocation builder creation events.

258

259

```java { .api }

260

/**

261

* Listener for invocation builder creation events

262

*/

263

public interface InvocationBuilderListener {

264

/**

265

* Called when a new invocation builder is created

266

* @param builder newly created invocation builder

267

* @param config configuration associated with the builder

268

*/

269

void onNewBuilder(Invocation.Builder builder, Configuration config);

270

}

271

```

272

273

### Pre-Invocation Interceptor

274

275

Interceptor interface for processing requests before they are executed.

276

277

```java { .api }

278

/**

279

* Interceptor for pre-request processing

280

*/

281

public interface PreInvocationInterceptor {

282

/**

283

* Called before request execution

284

* @param requestContext client request context for modification

285

*/

286

void beforeRequest(ClientRequestContext requestContext);

287

}

288

```

289

290

### Post-Invocation Interceptor

291

292

Interceptor interface for processing requests after they are executed or when exceptions occur.

293

294

```java { .api }

295

/**

296

* Interceptor for post-request processing

297

*/

298

public interface PostInvocationInterceptor {

299

/**

300

* Called after successful request execution

301

* @param requestContext client request context

302

* @param responseContext client response context

303

*/

304

void afterRequest(ClientRequestContext requestContext, ClientResponseContext responseContext);

305

306

/**

307

* Called when request execution fails with exception

308

* @param requestContext client request context

309

* @param exceptionContext exception context with failure details

310

*/

311

void onException(ClientRequestContext requestContext, ExceptionContext exceptionContext);

312

}

313

```

314

315

**Usage Examples:**

316

317

```java

318

// Custom pre-invocation interceptor for logging

319

public class LoggingPreInterceptor implements PreInvocationInterceptor {

320

@Override

321

public void beforeRequest(ClientRequestContext requestContext) {

322

System.out.println("Executing request: " +

323

requestContext.getMethod() + " " + requestContext.getUri());

324

325

// Add custom headers

326

requestContext.getHeaders().add("X-Request-ID", generateRequestId());

327

requestContext.getHeaders().add("X-Client-Version", "1.0.0");

328

}

329

}

330

331

// Custom post-invocation interceptor for metrics

332

public class MetricsPostInterceptor implements PostInvocationInterceptor {

333

@Override

334

public void afterRequest(ClientRequestContext requestContext,

335

ClientResponseContext responseContext) {

336

long duration = System.currentTimeMillis() - getRequestStartTime(requestContext);

337

recordMetrics(requestContext.getMethod(),

338

responseContext.getStatus(),

339

duration);

340

}

341

342

@Override

343

public void onException(ClientRequestContext requestContext,

344

ExceptionContext exceptionContext) {

345

recordFailure(requestContext.getMethod(),

346

exceptionContext.getThrowable().getClass().getSimpleName());

347

}

348

}

349

350

// Register interceptors with client

351

Client client = JerseyClientBuilder.createClient()

352

.register(new LoggingPreInterceptor())

353

.register(new MetricsPostInterceptor());

354

```

355

356

### Custom Connector Implementation

357

358

Example of implementing a custom connector for specialized HTTP transport needs.

359

360

**Usage Examples:**

361

362

```java

363

// Custom connector implementation

364

public class CustomHttpConnector implements Connector {

365

private final String name;

366

private final HttpClient httpClient; // Your preferred HTTP client

367

368

public CustomHttpConnector(String name, HttpClient httpClient) {

369

this.name = name;

370

this.httpClient = httpClient;

371

}

372

373

@Override

374

public ClientResponse apply(ClientRequest request) {

375

try {

376

// Convert Jersey ClientRequest to your HTTP client request

377

HttpRequest httpRequest = convertRequest(request);

378

379

// Execute request

380

HttpResponse httpResponse = httpClient.execute(httpRequest);

381

382

// Convert response back to Jersey ClientResponse

383

return convertResponse(httpResponse);

384

} catch (Exception e) {

385

throw new ProcessingException("Request execution failed", e);

386

}

387

}

388

389

@Override

390

public Future<?> apply(ClientRequest request, AsyncConnectorCallback callback) {

391

return CompletableFuture.runAsync(() -> {

392

try {

393

ClientResponse response = apply(request);

394

callback.response(response);

395

} catch (Exception e) {

396

callback.failure(e);

397

}

398

});

399

}

400

401

@Override

402

public String getName() {

403

return name;

404

}

405

406

@Override

407

public void close() {

408

if (httpClient != null) {

409

httpClient.close();

410

}

411

}

412

413

private HttpRequest convertRequest(ClientRequest clientRequest) {

414

// Implementation details for request conversion

415

return null;

416

}

417

418

private ClientResponse convertResponse(HttpResponse httpResponse) {

419

// Implementation details for response conversion

420

return null;

421

}

422

}

423

424

// Custom connector provider

425

public class CustomHttpConnectorProvider implements ConnectorProvider {

426

private final HttpClient httpClient;

427

428

public CustomHttpConnectorProvider(HttpClient httpClient) {

429

this.httpClient = httpClient;

430

}

431

432

@Override

433

public Connector getConnector(Client client, Configuration runtimeConfig) {

434

return new CustomHttpConnector("custom-http", httpClient);

435

}

436

}

437

438

// Use custom connector

439

HttpClient customHttpClient = createCustomHttpClient();

440

ConnectorProvider customProvider = new CustomHttpConnectorProvider(customHttpClient);

441

442

ClientConfig config = new ClientConfig();

443

config.connectorProvider(customProvider);

444

Client client = JerseyClientBuilder.createClient(config);

445

```

446

447

### Service Provider Integration

448

449

Integration with Java's ServiceLoader mechanism for automatic discovery of SPI implementations.

450

451

**Usage Examples:**

452

453

```java

454

// Service provider configuration (META-INF/services/org.glassfish.jersey.client.spi.ConnectorProvider)

455

// com.example.MyCustomConnectorProvider

456

457

// Automatic discovery and ranking

458

public class MyCustomConnectorProvider implements ConnectorProvider {

459

@Override

460

public Connector getConnector(Client client, Configuration runtimeConfig) {

461

return new MyCustomConnector();

462

}

463

}

464

465

// SPI implementations are automatically discovered and can be ranked using @Priority

466

@Priority(Priorities.USER)

467

public class HighPriorityConnectorProvider implements ConnectorProvider {

468

// Higher priority implementation

469

}

470

471

// Client will automatically use discovered implementations based on priority

472

Client client = JerseyClientBuilder.createClient(); // Uses discovered providers

473

```