CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-glassfish-jersey-core--jersey-client

Jersey core client implementation for building RESTful web service clients using JAX-RS API

Pending
Overview
Eval results
Files

connectors-spi.mddocs/

Connectors and SPI

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.

Capabilities

Connector Provider Interface

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

/**
 * Contract for providing client transport connectors
 */
public interface ConnectorProvider {
    /**
     * Create connector instance for the given client and configuration
     * @param client client instance requesting the connector
     * @param runtimeConfig runtime configuration for the connector
     * @return configured connector instance
     */
    Connector getConnector(Client client, Configuration runtimeConfig);
}

Connector Interface

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

/**
 * Client transport connector for executing HTTP requests
 */
public interface Connector extends Inflector<ClientRequest, ClientResponse> {
    /**
     * Execute HTTP request synchronously
     * @param request client request to execute
     * @return client response
     */
    ClientResponse apply(ClientRequest request);
    
    /**
     * Execute HTTP request asynchronously
     * @param request client request to execute
     * @param callback callback for handling response or failure
     * @return Future representing the async operation
     */
    Future<?> apply(ClientRequest request, AsyncConnectorCallback callback);
    
    /**
     * Get connector name for identification
     * @return connector name
     */
    String getName();
    
    /**
     * Close connector and release resources
     */
    void close();
}

Async Connector Callback

Callback interface for handling asynchronous HTTP request results and failures.

/**
 * Callback interface for asynchronous connector operations
 */
public interface AsyncConnectorCallback {
    /**
     * Handle successful response
     * @param response client response from successful request
     */
    void response(ClientResponse response);
    
    /**
     * Handle request failure
     * @param failure throwable representing the failure cause
     */
    void failure(Throwable failure);
}

HTTP URL Connector Provider

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

public class HttpUrlConnectorProvider implements ConnectorProvider {
    // Configuration properties
    public static final String USE_FIXED_LENGTH_STREAMING = "jersey.config.client.httpUrlConnector.useFixedLengthStreaming";
    public static final String SET_METHOD_WORKAROUND = "jersey.config.client.httpUrlConnector.setMethodWorkaround";
    
    /**
     * Create default HTTP URL connector provider
     */
    public HttpUrlConnectorProvider();
    
    /**
     * Configure connector with custom connection factory
     * @param connectionFactory factory for creating HTTP connections
     * @return configured connector provider
     */
    public HttpUrlConnectorProvider connectionFactory(ConnectionFactory connectionFactory);
    
    /**
     * Configure chunk size for chunked encoding
     * @param chunkSize chunk size in bytes
     * @return configured connector provider
     */
    public HttpUrlConnectorProvider chunkSize(int chunkSize);
    
    /**
     * Enable fixed-length streaming mode
     * @return configured connector provider
     */
    public HttpUrlConnectorProvider useFixedLengthStreaming();
    
    /**
     * Enable HTTP method workaround for restricted methods
     * @return configured connector provider
     */
    public HttpUrlConnectorProvider useSetMethodWorkaround();
    
    /**
     * Create connector instance
     * @param client client instance
     * @param config runtime configuration
     * @return HTTP URL connector instance
     */
    public Connector getConnector(Client client, Configuration config);
}

Connection Factory

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

/**
 * Factory for creating HTTP URL connections
 */
public interface ConnectionFactory {
    /**
     * Create HTTP connection for the given URL
     * @param url target URL for connection
     * @return HTTP URL connection
     * @throws IOException if connection creation fails
     */
    HttpURLConnection getConnection(URL url) throws IOException;
    
    /**
     * Create HTTP connection for the given URL with proxy
     * @param url target URL for connection
     * @param proxy proxy for connection
     * @return HTTP URL connection
     * @throws IOException if connection creation fails
     */
    default HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {
        return getConnection(url);
    }
}

Usage Examples:

import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.Proxy;

// Custom connection factory
HttpUrlConnectorProvider.ConnectionFactory customFactory = new HttpUrlConnectorProvider.ConnectionFactory() {
    @Override
    public HttpURLConnection getConnection(URL url) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(30000);
        return connection;
    }
    
    @Override
    public HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(30000);
        return connection;
    }
};

// Configure client with custom connector
HttpUrlConnectorProvider connectorProvider = new HttpUrlConnectorProvider()
    .connectionFactory(customFactory)
    .chunkSize(8192)
    .useFixedLengthStreaming();

ClientConfig config = new ClientConfig();
config.connectorProvider(connectorProvider);
Client client = JerseyClientBuilder.createClient(config);

Caching Connector Provider

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

public class CachingConnectorProvider implements ConnectorProvider {
    /**
     * Create caching wrapper for the given connector provider
     * @param delegate underlying connector provider to cache
     */
    public CachingConnectorProvider(ConnectorProvider delegate);
    
    /**
     * Get connector instance (cached if previously created)
     * @param client client instance
     * @param runtimeConfig runtime configuration
     * @return cached or new connector instance
     */
    public Connector getConnector(Client client, Configuration runtimeConfig);
}

Usage Examples:

// Wrap any connector provider with caching
ConnectorProvider baseProvider = new HttpUrlConnectorProvider();
ConnectorProvider cachingProvider = new CachingConnectorProvider(baseProvider);

ClientConfig config = new ClientConfig();
config.connectorProvider(cachingProvider);
Client client = JerseyClientBuilder.createClient(config);

Client Builder Listener

Listener interface for intercepting client builder creation events.

/**
 * Listener for client builder creation events
 */
public interface ClientBuilderListener {
    /**
     * Called when a new client builder is created
     * @param builder newly created client builder
     */
    void onNewBuilder(ClientBuilder builder);
}

Invocation Builder Listener

Listener interface for intercepting invocation builder creation events.

/**
 * Listener for invocation builder creation events
 */
public interface InvocationBuilderListener {
    /**
     * Called when a new invocation builder is created
     * @param builder newly created invocation builder
     * @param config configuration associated with the builder
     */
    void onNewBuilder(Invocation.Builder builder, Configuration config);
}

Pre-Invocation Interceptor

Interceptor interface for processing requests before they are executed.

/**
 * Interceptor for pre-request processing
 */
public interface PreInvocationInterceptor {
    /**
     * Called before request execution
     * @param requestContext client request context for modification
     */
    void beforeRequest(ClientRequestContext requestContext);
}

Post-Invocation Interceptor

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

/**
 * Interceptor for post-request processing
 */
public interface PostInvocationInterceptor {
    /**
     * Called after successful request execution
     * @param requestContext client request context
     * @param responseContext client response context
     */
    void afterRequest(ClientRequestContext requestContext, ClientResponseContext responseContext);
    
    /**
     * Called when request execution fails with exception
     * @param requestContext client request context
     * @param exceptionContext exception context with failure details
     */
    void onException(ClientRequestContext requestContext, ExceptionContext exceptionContext);
}

Usage Examples:

// Custom pre-invocation interceptor for logging
public class LoggingPreInterceptor implements PreInvocationInterceptor {
    @Override
    public void beforeRequest(ClientRequestContext requestContext) {
        System.out.println("Executing request: " + 
            requestContext.getMethod() + " " + requestContext.getUri());
        
        // Add custom headers
        requestContext.getHeaders().add("X-Request-ID", generateRequestId());
        requestContext.getHeaders().add("X-Client-Version", "1.0.0");
    }
}

// Custom post-invocation interceptor for metrics
public class MetricsPostInterceptor implements PostInvocationInterceptor {
    @Override
    public void afterRequest(ClientRequestContext requestContext, 
                           ClientResponseContext responseContext) {
        long duration = System.currentTimeMillis() - getRequestStartTime(requestContext);
        recordMetrics(requestContext.getMethod(), 
                     responseContext.getStatus(), 
                     duration);
    }
    
    @Override
    public void onException(ClientRequestContext requestContext, 
                          ExceptionContext exceptionContext) {
        recordFailure(requestContext.getMethod(), 
                     exceptionContext.getThrowable().getClass().getSimpleName());
    }
}

// Register interceptors with client
Client client = JerseyClientBuilder.createClient()
    .register(new LoggingPreInterceptor())
    .register(new MetricsPostInterceptor());

Custom Connector Implementation

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

Usage Examples:

// Custom connector implementation
public class CustomHttpConnector implements Connector {
    private final String name;
    private final HttpClient httpClient; // Your preferred HTTP client
    
    public CustomHttpConnector(String name, HttpClient httpClient) {
        this.name = name;
        this.httpClient = httpClient;
    }
    
    @Override
    public ClientResponse apply(ClientRequest request) {
        try {
            // Convert Jersey ClientRequest to your HTTP client request
            HttpRequest httpRequest = convertRequest(request);
            
            // Execute request
            HttpResponse httpResponse = httpClient.execute(httpRequest);
            
            // Convert response back to Jersey ClientResponse
            return convertResponse(httpResponse);
        } catch (Exception e) {
            throw new ProcessingException("Request execution failed", e);
        }
    }
    
    @Override
    public Future<?> apply(ClientRequest request, AsyncConnectorCallback callback) {
        return CompletableFuture.runAsync(() -> {
            try {
                ClientResponse response = apply(request);
                callback.response(response);
            } catch (Exception e) {
                callback.failure(e);
            }
        });
    }
    
    @Override
    public String getName() {
        return name;
    }
    
    @Override
    public void close() {
        if (httpClient != null) {
            httpClient.close();
        }
    }
    
    private HttpRequest convertRequest(ClientRequest clientRequest) {
        // Implementation details for request conversion
        return null;
    }
    
    private ClientResponse convertResponse(HttpResponse httpResponse) {
        // Implementation details for response conversion
        return null;
    }
}

// Custom connector provider
public class CustomHttpConnectorProvider implements ConnectorProvider {
    private final HttpClient httpClient;
    
    public CustomHttpConnectorProvider(HttpClient httpClient) {
        this.httpClient = httpClient;
    }
    
    @Override
    public Connector getConnector(Client client, Configuration runtimeConfig) {
        return new CustomHttpConnector("custom-http", httpClient);
    }
}

// Use custom connector
HttpClient customHttpClient = createCustomHttpClient();
ConnectorProvider customProvider = new CustomHttpConnectorProvider(customHttpClient);

ClientConfig config = new ClientConfig();
config.connectorProvider(customProvider);
Client client = JerseyClientBuilder.createClient(config);

Service Provider Integration

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

Usage Examples:

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

// Automatic discovery and ranking
public class MyCustomConnectorProvider implements ConnectorProvider {
    @Override
    public Connector getConnector(Client client, Configuration runtimeConfig) {
        return new MyCustomConnector();
    }
}

// SPI implementations are automatically discovered and can be ranked using @Priority
@Priority(Priorities.USER)
public class HighPriorityConnectorProvider implements ConnectorProvider {
    // Higher priority implementation
}

// Client will automatically use discovered implementations based on priority
Client client = JerseyClientBuilder.createClient(); // Uses discovered providers

Install with Tessl CLI

npx tessl i tessl/maven-org-glassfish-jersey-core--jersey-client

docs

authentication.md

client-config.md

connectors-spi.md

filters-features.md

index.md

request-execution.md

tile.json