CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-javax-ws-rs--javax-ws-rs-api

Java API for RESTful Web Services

Pending
Overview
Eval results
Files

client-api.mddocs/

Client API

The JAX-RS Client API provides a fluent interface for consuming RESTful web services. It supports synchronous, asynchronous, and reactive invocation patterns with built-in support for request/response filtering, configuration, and entity processing.

Core Imports

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.AsyncInvoker;
import javax.ws.rs.client.SyncInvoker;
import javax.ws.rs.client.InvocationCallback;
import javax.ws.rs.client.RxInvoker;
import javax.ws.rs.client.CompletionStageRxInvoker;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ResponseProcessingException;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Configuration;

import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.WriterInterceptor;

import java.util.concurrent.Future;
import java.util.concurrent.CompletionStage;
import java.io.IOException;

Client Creation

ClientBuilder

Main entry point for creating Client instances.

public abstract class ClientBuilder implements Configurable<ClientBuilder> {
    
    public static ClientBuilder newBuilder();
    public static Client newClient();
    public static Client newClient(Configuration configuration);
    
    public abstract ClientBuilder withConfig(Configuration config);
    public abstract Client build();
}

Client Interface

Main client interface for building requests.

public interface Client extends Configurable<Client> {
    
    void close();
    
    WebTarget target(String uri);
    WebTarget target(URI uri);
    WebTarget target(UriBuilder uriBuilder);
    WebTarget target(Link link);
    
    Invocation.Builder invocation(Link link);
}

Basic Client Usage:

// Create client
Client client = ClientBuilder.newClient();

// Simple GET request
Response response = client.target("https://api.example.com/users/123")
                         .request(MediaType.APPLICATION_JSON)
                         .get();

if (response.getStatus() == 200) {
    User user = response.readEntity(User.class);
    System.out.println("User: " + user.getName());
}

// Always close the client
client.close();

WebTarget Interface

Represents a resource target identified by URI.

public interface WebTarget extends Configurable<WebTarget> {
    
    URI getUri();
    UriBuilder getUriBuilder();
    
    WebTarget path(String path);
    WebTarget resolveTemplate(String name, Object value);
    WebTarget resolveTemplate(String name, Object value, boolean encodeSlashInPath);
    WebTarget resolveTemplateFromEncoded(String name, Object value);
    WebTarget resolveTemplates(Map<String, Object> templateValues);
    WebTarget resolveTemplates(Map<String, Object> templateValues, boolean encodeSlashInPath);
    WebTarget resolveTemplatesFromEncoded(Map<String, Object> templateValues);
    
    WebTarget matrixParam(String name, Object... values);
    WebTarget queryParam(String name, Object... values);
    
    Invocation.Builder request();
    Invocation.Builder request(String... acceptedResponseTypes);
    Invocation.Builder request(MediaType... acceptedResponseTypes);
}

WebTarget Usage Examples:

Client client = ClientBuilder.newClient();

// Building complex URIs
WebTarget baseTarget = client.target("https://api.example.com");

// Path building
WebTarget usersTarget = baseTarget.path("/users").path("/{userId}");

// Template resolution
WebTarget specificUser = usersTarget.resolveTemplate("userId", "123");

// Query parameters
WebTarget searchTarget = baseTarget.path("/search")
                                  .queryParam("q", "java")
                                  .queryParam("limit", 10)
                                  .queryParam("offset", 0);

// Matrix parameters
WebTarget productsTarget = baseTarget.path("/products")
                                    .matrixParam("color", "red")
                                    .matrixParam("size", "large");

// Execute requests
Response userResponse = specificUser.request(MediaType.APPLICATION_JSON).get();
Response searchResponse = searchTarget.request(MediaType.APPLICATION_JSON).get();

Invocation Building

Invocation and Builder Interfaces

public interface Invocation {
    
    Invocation property(String name, Object value);
    Response invoke();
    <T> T invoke(Class<T> responseType);
    <T> T invoke(GenericType<T> responseType);
    
    Future<Response> submit();
    <T> Future<T> submit(Class<T> responseType);
    <T> Future<T> submit(GenericType<T> responseType);
    <T> Future<T> submit(InvocationCallback<T> callback);
}

public static interface Invocation.Builder extends SyncInvoker {
    
    Invocation build(String method);
    Invocation build(String method, Entity<?> entity);
    Invocation buildGet();
    Invocation buildDelete();
    Invocation buildPost(Entity<?> entity);
    Invocation buildPut(Entity<?> entity);
    
    AsyncInvoker async();
    
    Invocation.Builder accept(String... mediaTypes);
    Invocation.Builder accept(MediaType... mediaTypes);
    Invocation.Builder acceptLanguage(Locale... locales);
    Invocation.Builder acceptLanguage(String... locales);
    Invocation.Builder acceptEncoding(String... encodings);
    Invocation.Builder cookie(Cookie cookie);
    Invocation.Builder cookie(String name, String value);
    Invocation.Builder cacheControl(CacheControl cacheControl);
    Invocation.Builder header(String name, Object value);
    Invocation.Builder headers(MultivaluedMap<String, Object> headers);
    Invocation.Builder property(String name, Object value);
    
    CompletionStageRxInvoker rx();
    <T extends RxInvoker> T rx(Class<T> clazz);
}

Synchronous Invocations

SyncInvoker Interface

public interface SyncInvoker {
    
    Response get();
    <T> T get(Class<T> responseType);
    <T> T get(GenericType<T> responseType);
    
    Response put(Entity<?> entity);
    <T> T put(Entity<?> entity, Class<T> responseType);
    <T> T put(Entity<?> entity, GenericType<T> responseType);
    
    Response post(Entity<?> entity);
    <T> T post(Entity<?> entity, Class<T> responseType);
    <T> T post(Entity<?> entity, GenericType<T> responseType);
    
    Response delete();
    <T> T delete(Class<T> responseType);
    <T> T delete(GenericType<T> responseType);
    
    Response head();
    Response options();
    <T> T options(Class<T> responseType);
    <T> T options(GenericType<T> responseType);
    
    Response trace();
    <T> T trace(Class<T> responseType);
    <T> T trace(GenericType<T> responseType);
    
    Response method(String name);
    <T> T method(String name, Class<T> responseType);
    <T> T method(String name, GenericType<T> responseType);
    Response method(String name, Entity<?> entity);
    <T> T method(String name, Entity<?> entity, Class<T> responseType);
    <T> T method(String name, Entity<?> entity, GenericType<T> responseType);
}

Synchronous Usage Examples:

Client client = ClientBuilder.newClient();
WebTarget target = client.target("https://api.example.com/users");

// GET requests
User user = target.path("/123")
                 .request(MediaType.APPLICATION_JSON)
                 .get(User.class);

// GET with response inspection
Response response = target.path("/123")
                         .request(MediaType.APPLICATION_JSON)
                         .get();
if (response.getStatus() == 200) {
    User user = response.readEntity(User.class);
}

// POST requests
User newUser = new User("John", "john@example.com");
User created = target.request(MediaType.APPLICATION_JSON)
                    .post(Entity.json(newUser), User.class);

// PUT requests  
User updatedUser = target.path("/123")
                        .request(MediaType.APPLICATION_JSON)
                        .put(Entity.json(user), User.class);

// DELETE requests
Response deleteResponse = target.path("/123")
                               .request()
                               .delete();

// Custom headers
User userWithAuth = target.path("/123")
                         .request(MediaType.APPLICATION_JSON)
                         .header("Authorization", "Bearer " + token)
                         .header("X-Client-Version", "1.0")
                         .get(User.class);

// Generic types for collections
List<User> users = target.request(MediaType.APPLICATION_JSON)
                        .get(new GenericType<List<User>>(){});

Asynchronous Invocations

AsyncInvoker Interface

public interface AsyncInvoker {
    
    Future<Response> get();
    <T> Future<T> get(Class<T> responseType);
    <T> Future<T> get(GenericType<T> responseType);
    <T> Future<T> get(InvocationCallback<T> callback);
    
    Future<Response> put(Entity<?> entity);
    <T> Future<T> put(Entity<?> entity, Class<T> responseType);
    <T> Future<T> put(Entity<?> entity, GenericType<T> responseType);
    <T> Future<T> put(Entity<?> entity, InvocationCallback<T> callback);
    
    Future<Response> post(Entity<?> entity);
    <T> Future<T> post(Entity<?> entity, Class<T> responseType);
    <T> Future<T> post(Entity<?> entity, GenericType<T> responseType);
    <T> Future<T> post(Entity<?> entity, InvocationCallback<T> callback);
    
    Future<Response> delete();
    <T> Future<T> delete(Class<T> responseType);
    <T> Future<T> delete(GenericType<T> responseType);
    <T> Future<T> delete(InvocationCallback<T> callback);
    
    Future<Response> head();
    Future<Response> head(InvocationCallback<Response> callback);
    
    Future<Response> options();
    <T> Future<T> options(Class<T> responseType);
    <T> Future<T> options(GenericType<T> responseType);
    <T> Future<T> options(InvocationCallback<T> callback);
    
    Future<Response> trace();
    <T> Future<T> trace(Class<T> responseType);
    <T> Future<T> trace(GenericType<T> responseType);
    <T> Future<T> trace(InvocationCallback<T> callback);
    
    Future<Response> method(String name);
    <T> Future<T> method(String name, Class<T> responseType);
    <T> Future<T> method(String name, GenericType<T> responseType);
    <T> Future<T> method(String name, InvocationCallback<T> callback);
    Future<Response> method(String name, Entity<?> entity);
    <T> Future<T> method(String name, Entity<?> entity, Class<T> responseType);
    <T> Future<T> method(String name, Entity<?> entity, GenericType<T> responseType);
    <T> Future<T> method(String name, Entity<?> entity, InvocationCallback<T> callback);
}

InvocationCallback Interface

public interface InvocationCallback<RESPONSE> {
    
    void completed(RESPONSE response);
    void failed(Throwable throwable);
}

Asynchronous Usage Examples:

Client client = ClientBuilder.newClient();
WebTarget target = client.target("https://api.example.com/users");

// Async with Future
Future<User> futureUser = target.path("/123")
                               .request(MediaType.APPLICATION_JSON)
                               .async()
                               .get(User.class);

// Wait for result
User user = futureUser.get(); // Blocks until completion

// Async with callback
target.path("/123")
      .request(MediaType.APPLICATION_JSON)
      .async()
      .get(new InvocationCallback<User>() {
          @Override
          public void completed(User user) {
              System.out.println("Received user: " + user.getName());
          }
          
          @Override
          public void failed(Throwable throwable) {
              System.err.println("Request failed: " + throwable.getMessage());
          }
      });

// Async POST with callback
User newUser = new User("Jane", "jane@example.com");
target.request(MediaType.APPLICATION_JSON)
      .async()
      .post(Entity.json(newUser), new InvocationCallback<User>() {
          @Override
          public void completed(User createdUser) {
              System.out.println("User created: " + createdUser.getId());
          }
          
          @Override
          public void failed(Throwable throwable) {
              System.err.println("User creation failed: " + throwable.getMessage());
          }
      });

Reactive Extensions

RxInvoker Interfaces

public interface RxInvoker<T> {
    
    T get();
    <R> T get(Class<R> responseType);
    <R> T get(GenericType<R> responseType);
    
    T put(Entity<?> entity);
    <R> T put(Entity<?> entity, Class<R> responseType);
    <R> T put(Entity<?> entity, GenericType<R> responseType);
    
    T post(Entity<?> entity);
    <R> T post(Entity<?> entity, Class<R> responseType);
    <R> T post(Entity<?> entity, GenericType<R> responseType);
    
    T delete();
    <R> T delete(Class<R> responseType);
    <R> T delete(GenericType<R> responseType);
    
    T head();
    T options();
    <R> T options(Class<R> responseType);
    <R> T options(GenericType<R> responseType);
    
    T trace();
    <R> T trace(Class<R> responseType);
    <R> T trace(GenericType<R> responseType);
    
    T method(String name);
    <R> T method(String name, Class<R> responseType);
    <R> T method(String name, GenericType<R> responseType);
    T method(String name, Entity<?> entity);
    <R> T method(String name, Entity<?> entity, Class<R> responseType);
    <R> T method(String name, Entity<?> entity, GenericType<R> responseType);
}

public interface CompletionStageRxInvoker extends RxInvoker<CompletionStage> {
}

Reactive Usage Examples:

import java.util.concurrent.CompletionStage;

Client client = ClientBuilder.newClient();
WebTarget target = client.target("https://api.example.com/users");

// CompletionStage-based reactive calls
CompletionStage<User> userStage = target.path("/123")
                                       .request(MediaType.APPLICATION_JSON)
                                       .rx()
                                       .get(User.class);

// Chain operations
userStage.thenCompose(user -> {
    // Load user's orders
    return target.path("/" + user.getId() + "/orders")
                .request(MediaType.APPLICATION_JSON)
                .rx()
                .get(new GenericType<List<Order>>(){});
}).thenAccept(orders -> {
    System.out.println("User has " + orders.size() + " orders");
}).exceptionally(throwable -> {
    System.err.println("Error: " + throwable.getMessage());
    return null;
});

// Parallel requests
CompletionStage<User> userStage = target.path("/123")
                                       .request(MediaType.APPLICATION_JSON)
                                       .rx()
                                       .get(User.class);

CompletionStage<List<Order>> ordersStage = target.path("/123/orders")
                                                .request(MediaType.APPLICATION_JSON)
                                                .rx()
                                                .get(new GenericType<List<Order>>(){});

// Combine results
userStage.thenCombine(ordersStage, (user, orders) -> {
    return new UserWithOrders(user, orders);
}).thenAccept(userWithOrders -> {
    System.out.println("Complete user data loaded");
});

Entity Processing

Entity Class

Encapsulates message entity with variant information.

public final class Entity<T> {
    
    public static <T> Entity<T> entity(T entity, MediaType mediaType);
    public static <T> Entity<T> entity(T entity, String mediaType);
    public static <T> Entity<T> entity(T entity, Variant variant);
    
    public static <T> Entity<T> json(T entity);
    public static <T> Entity<T> xml(T entity);
    public static <T> Entity<T> html(T entity);
    public static <T> Entity<T> text(T entity);
    public static <T> Entity<T> xhtml(T entity);
    public static Entity<Form> form(Form form);
    public static Entity<Form> form(MultivaluedMap<String, String> formData);
    
    public Variant getVariant();
    public MediaType getMediaType();
    public String getEncoding();
    public Locale getLanguage();
    public T getEntity();
    
    public Annotation[] getAnnotations();
}

Entity Usage Examples:

Client client = ClientBuilder.newClient();
WebTarget target = client.target("https://api.example.com/users");

// JSON entity
User user = new User("John", "john@example.com");
Response response = target.request(MediaType.APPLICATION_JSON)
                         .post(Entity.json(user));

// XML entity
User xmlUser = target.request(MediaType.APPLICATION_XML)
                    .post(Entity.xml(user), User.class);

// Custom media type
User customUser = target.request("application/vnd.api+json")
                       .post(Entity.entity(user, "application/vnd.api+json"), User.class);

// Form data
MultivaluedMap<String, String> formData = new MultivaluedHashMap<>();
formData.add("name", "John");
formData.add("email", "john@example.com");

Response formResponse = target.request()
                             .post(Entity.form(formData));

// Form object
Form form = new Form();
form.param("name", "John");
form.param("email", "john@example.com");

Response formObjectResponse = target.request()
                                   .post(Entity.form(form));

Client Configuration and Filtering

JAX-RS clients support configuration and filtering for cross-cutting concerns.

Configuration Example:

// Custom client configuration
Client client = ClientBuilder.newBuilder()
    .connectTimeout(5, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .register(new LoggingFilter())
    .register(new AuthenticationFilter())
    .build();

// Per-request configuration
Response response = client.target("https://api.example.com/users")
                         .property("custom.timeout", 10000)
                         .request(MediaType.APPLICATION_JSON)
                         .header("X-API-Key", apiKey)
                         .get();

Client Filters and Interceptors

Client Request Filter

Interface for filtering client requests before they are sent to the server.

@FunctionalInterface
public interface ClientRequestFilter {
    void filter(ClientRequestContext requestContext) throws IOException;
}

Client Response Filter

Interface for filtering client responses after they are received from the server.

@FunctionalInterface
public interface ClientResponseFilter {
    void filter(ClientRequestContext requestContext, 
                ClientResponseContext responseContext) throws IOException;
}

Client Request Context

Provides access to request context during client-side filtering.

public interface ClientRequestContext {
    Object getProperty(String name);
    Collection<String> getPropertyNames();
    void setProperty(String name, Object object);
    void removeProperty(String name);
    
    URI getUri();
    void setUri(URI uri);
    String getMethod();
    void setMethod(String method);
    
    MultivaluedMap<String, Object> getHeaders();
    MultivaluedMap<String, String> getStringHeaders();
    String getHeaderString(String name);
    
    Date getDate();
    Locale getLanguage();
    MediaType getMediaType();
    List<MediaType> getAcceptableMediaTypes();
    List<Locale> getAcceptableLanguages();
    
    Map<String, Cookie> getCookies();
    boolean hasEntity();
    Object getEntity();
    void setEntity(Object entity);
    void setEntity(Object entity, Annotation[] annotations, MediaType mediaType);
    
    Class<?> getEntityClass();
    Type getEntityType();
    Annotation[] getEntityAnnotations();
    OutputStream getEntityStream();
    void setEntityStream(OutputStream outputStream);
    
    Client getClient();
    Configuration getConfiguration();
    void abortWith(Response response);
}

Client Response Context

Provides access to response context during client-side filtering.

public interface ClientResponseContext {
    int getStatus();
    void setStatus(int code);
    Response.StatusType getStatusInfo();
    void setStatusInfo(Response.StatusType statusInfo);
    
    MultivaluedMap<String, String> getHeaders();
    String getHeaderString(String name);
    Set<String> getAllowedMethods();
    Date getDate();
    Date getLastModified();
    Locale getLanguage();
    int getLength();
    MediaType getMediaType();
    Map<String, NewCookie> getCookies();
    EntityTag getEntityTag();
    
    boolean hasEntity();
    InputStream getEntityStream();
    void setEntityStream(InputStream input);
}

Client Filter Usage Example:

// Authentication filter
@Provider
public class BearerTokenFilter implements ClientRequestFilter {
    private final String token;
    
    public BearerTokenFilter(String token) {
        this.token = token;
    }
    
    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        requestContext.getHeaders().add("Authorization", "Bearer " + token);
    }
}

// Logging filter  
@Provider
public class ClientLoggingFilter implements ClientRequestFilter, ClientResponseFilter {
    
    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        System.out.println("Request: " + requestContext.getMethod() + " " + requestContext.getUri());
    }
    
    @Override
    public void filter(ClientRequestContext requestContext, 
                      ClientResponseContext responseContext) throws IOException {
        System.out.println("Response: " + responseContext.getStatus());
    }
}

// Register filters
Client client = ClientBuilder.newBuilder()
    .register(new BearerTokenFilter("abc123"))
    .register(new ClientLoggingFilter())
    .build();

Exception Handling

Client-Side Exceptions

public class ProcessingException extends RuntimeException {
    public ProcessingException(String message);
    public ProcessingException(String message, Throwable cause);
    public ProcessingException(Throwable cause);
}

public class ResponseProcessingException extends ProcessingException {
    public ResponseProcessingException(Response response, String message);
    public ResponseProcessingException(Response response, String message, Throwable cause);
    public ResponseProcessingException(Response response, Throwable cause);
    
    public Response getResponse();
}

Exception Handling Example:

try {
    User user = client.target("https://api.example.com/users/123")
                     .request(MediaType.APPLICATION_JSON)
                     .get(User.class);
} catch (ProcessingException e) {
    // Network or processing error
    System.err.println("Request processing failed: " + e.getMessage());
} catch (WebApplicationException e) {
    // HTTP error response (4xx, 5xx)
    Response response = e.getResponse();
    System.err.println("HTTP error " + response.getStatus() + ": " + 
                       response.readEntity(String.class));
}

Install with Tessl CLI

npx tessl i tessl/maven-javax-ws-rs--javax-ws-rs-api

docs

client-api.md

core-types.md

extensions.md

index.md

resource-endpoints.md

server-container.md

server-sent-events.md

tile.json