or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-api.mdcore-types.mdextensions.mdindex.mdresource-endpoints.mdserver-container.mdserver-sent-events.md

server-container.mddocs/

0

# Server Container

1

2

The server container APIs provide server-side processing capabilities including request/response filtering, asynchronous processing, resource management, and dynamic configuration. These APIs enable cross-cutting concerns like authentication, logging, caching, and custom request processing.

3

4

## Core Imports

5

6

```java

7

import javax.ws.rs.container.ContainerRequestContext;

8

import javax.ws.rs.container.ContainerResponseContext;

9

import javax.ws.rs.container.ContainerRequestFilter;

10

import javax.ws.rs.container.ContainerResponseFilter;

11

import javax.ws.rs.container.DynamicFeature;

12

import javax.ws.rs.core.FeatureContext;

13

import javax.ws.rs.container.PreMatching;

14

import javax.ws.rs.container.Suspended;

15

16

import javax.ws.rs.container.AsyncResponse;

17

import javax.ws.rs.container.CompletionCallback;

18

import javax.ws.rs.container.ConnectionCallback;

19

import javax.ws.rs.container.TimeoutHandler;

20

21

import javax.ws.rs.container.ResourceContext;

22

import javax.ws.rs.container.ResourceInfo;

23

24

import javax.ws.rs.core.Response;

25

import javax.ws.rs.ext.Provider;

26

27

import java.io.IOException;

28

import java.util.concurrent.TimeUnit;

29

```

30

31

## Request and Response Context

32

33

### ContainerRequestContext Interface

34

35

Provides access to request processing information on the server side.

36

37

```java { .api }

38

public interface ContainerRequestContext {

39

40

Object getProperty(String name);

41

Collection<String> getPropertyNames();

42

void setProperty(String name, Object object);

43

void removeProperty(String name);

44

45

UriInfo getUriInfo();

46

void setRequestUri(URI requestUri);

47

void setRequestUri(URI baseUri, URI requestUri);

48

49

Request getRequest();

50

String getMethod();

51

void setMethod(String method);

52

53

MultivaluedMap<String, String> getHeaders();

54

String getHeaderString(String name);

55

56

Date getDate();

57

Locale getLanguage();

58

int getLength();

59

MediaType getMediaType();

60

List<MediaType> getAcceptableMediaTypes();

61

List<Locale> getAcceptableLanguages();

62

63

Map<String, Cookie> getCookies();

64

65

boolean hasEntity();

66

InputStream getEntityStream();

67

void setEntityStream(InputStream input);

68

69

SecurityContext getSecurityContext();

70

void setSecurityContext(SecurityContext context);

71

72

void abortWith(Response response);

73

}

74

```

75

76

### ContainerResponseContext Interface

77

78

Provides access to response processing information on the server side.

79

80

```java { .api }

81

public interface ContainerResponseContext {

82

83

int getStatus();

84

void setStatus(int code);

85

StatusType getStatusInfo();

86

void setStatusInfo(StatusType statusInfo);

87

88

MultivaluedMap<String, Object> getHeaders();

89

MultivaluedMap<String, String> getStringHeaders();

90

String getHeaderString(String name);

91

92

Set<String> getAllowedMethods();

93

94

Date getDate();

95

Date getLastModified();

96

URI getLocation();

97

Set<Link> getLinks();

98

boolean hasLink(String relation);

99

Link getLink(String relation);

100

Link.Builder getLinkBuilder(String relation);

101

102

boolean hasEntity();

103

Object getEntity();

104

Class<?> getEntityClass();

105

Type getEntityType();

106

void setEntity(Object entity);

107

void setEntity(Object entity, Annotation[] annotations, MediaType mediaType);

108

109

Annotation[] getEntityAnnotations();

110

MediaType getMediaType();

111

112

OutputStream getEntityStream();

113

void setEntityStream(OutputStream outputStream);

114

}

115

```

116

117

## Request and Response Filters

118

119

### ContainerRequestFilter Interface

120

121

Filters incoming server requests.

122

123

```java { .api }

124

@Provider

125

public interface ContainerRequestFilter {

126

127

void filter(ContainerRequestContext requestContext) throws IOException;

128

}

129

```

130

131

### ContainerResponseFilter Interface

132

133

Filters outgoing server responses.

134

135

```java { .api }

136

@Provider

137

public interface ContainerResponseFilter {

138

139

void filter(ContainerRequestContext requestContext,

140

ContainerResponseContext responseContext) throws IOException;

141

}

142

```

143

144

**Filter Implementation Examples:**

145

146

```java

147

// Authentication filter

148

@Provider

149

@Priority(Priorities.AUTHENTICATION)

150

public class AuthenticationFilter implements ContainerRequestFilter {

151

152

@Override

153

public void filter(ContainerRequestContext requestContext) throws IOException {

154

String authorization = requestContext.getHeaderString("Authorization");

155

156

if (authorization == null || !authorization.startsWith("Bearer ")) {

157

requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)

158

.entity("Authentication required")

159

.build());

160

return;

161

}

162

163

String token = authorization.substring("Bearer ".length());

164

if (!isValidToken(token)) {

165

requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)

166

.entity("Invalid token")

167

.build());

168

}

169

}

170

171

private boolean isValidToken(String token) {

172

// Token validation logic

173

return tokenService.validate(token);

174

}

175

}

176

177

// Logging filter

178

@Provider

179

public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {

180

181

@Override

182

public void filter(ContainerRequestContext requestContext) throws IOException {

183

System.out.println("Request: " + requestContext.getMethod() + " " +

184

requestContext.getUriInfo().getRequestUri());

185

186

// Store request timestamp

187

requestContext.setProperty("request.timestamp", System.currentTimeMillis());

188

}

189

190

@Override

191

public void filter(ContainerRequestContext requestContext,

192

ContainerResponseContext responseContext) throws IOException {

193

Long startTime = (Long) requestContext.getProperty("request.timestamp");

194

long duration = System.currentTimeMillis() - startTime;

195

196

System.out.println("Response: " + responseContext.getStatus() +

197

" (took " + duration + "ms)");

198

}

199

}

200

201

// CORS filter

202

@Provider

203

@PreMatching

204

public class CorsFilter implements ContainerRequestFilter, ContainerResponseFilter {

205

206

@Override

207

public void filter(ContainerRequestContext requestContext) throws IOException {

208

if ("OPTIONS".equals(requestContext.getMethod())) {

209

requestContext.abortWith(Response.ok().build());

210

}

211

}

212

213

@Override

214

public void filter(ContainerRequestContext requestContext,

215

ContainerResponseContext responseContext) throws IOException {

216

responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");

217

responseContext.getHeaders().add("Access-Control-Allow-Methods",

218

"GET, POST, PUT, DELETE, OPTIONS");

219

responseContext.getHeaders().add("Access-Control-Allow-Headers",

220

"Content-Type, Authorization");

221

}

222

}

223

```

224

225

### @PreMatching Annotation

226

227

Marks filters to be executed before resource method matching.

228

229

```java { .api }

230

@Target({ElementType.TYPE})

231

@Retention(RetentionPolicy.RUNTIME)

232

@Documented

233

public @interface PreMatching {

234

}

235

```

236

237

**Pre-matching Filter Example:**

238

239

```java

240

@Provider

241

@PreMatching

242

@Priority(Priorities.HEADER_DECORATOR)

243

public class PreMatchingFilter implements ContainerRequestFilter {

244

245

@Override

246

public void filter(ContainerRequestContext requestContext) throws IOException {

247

// Modify request before resource matching

248

String userAgent = requestContext.getHeaderString("User-Agent");

249

if (userAgent != null && userAgent.contains("mobile")) {

250

// Redirect mobile users to mobile API

251

String uri = requestContext.getUriInfo().getRequestUri().toString();

252

String mobileUri = uri.replace("/api/", "/mobile-api/");

253

requestContext.setRequestUri(URI.create(mobileUri));

254

}

255

}

256

}

257

```

258

259

## Dynamic Configuration

260

261

### DynamicFeature Interface

262

263

Allows runtime configuration of providers based on resource information.

264

265

```java { .api }

266

public interface DynamicFeature {

267

268

void configure(ResourceInfo resourceInfo, FeatureContext context);

269

}

270

```

271

272

**Dynamic Feature Example:**

273

274

```java

275

@Provider

276

public class SecurityDynamicFeature implements DynamicFeature {

277

278

@Override

279

public void configure(ResourceInfo resourceInfo, FeatureContext context) {

280

Method method = resourceInfo.getResourceMethod();

281

282

// Apply authentication filter only to methods annotated with @Secured

283

if (method.isAnnotationPresent(Secured.class)) {

284

context.register(AuthenticationFilter.class);

285

}

286

287

// Apply admin filter to admin methods

288

if (method.isAnnotationPresent(AdminRequired.class)) {

289

context.register(AdminAuthorizationFilter.class, Priorities.AUTHORIZATION);

290

}

291

}

292

}

293

294

// Custom security annotations

295

@Retention(RetentionPolicy.RUNTIME)

296

@Target({ElementType.METHOD, ElementType.TYPE})

297

public @interface Secured {

298

}

299

300

@Retention(RetentionPolicy.RUNTIME)

301

@Target({ElementType.METHOD})

302

public @interface AdminRequired {

303

}

304

305

// Usage in resource

306

@Path("/admin")

307

public class AdminResource {

308

309

@GET

310

@Path("/users")

311

@Secured

312

@AdminRequired

313

public List<User> getAllUsers() {

314

return userService.findAll();

315

}

316

}

317

```

318

319

### FeatureContext Interface

320

321

Provides a context for configuring providers dynamically.

322

323

```java { .api }

324

public interface FeatureContext extends Configurable<FeatureContext> {

325

326

// Inherited from Configurable<FeatureContext>:

327

Configuration getConfiguration();

328

FeatureContext property(String name, Object value);

329

FeatureContext register(Class<?> componentClass);

330

FeatureContext register(Class<?> componentClass, int priority);

331

FeatureContext register(Class<?> componentClass, Class<?>... contracts);

332

FeatureContext register(Class<?> componentClass, Map<Class<?>, Integer> contracts);

333

FeatureContext register(Object component);

334

FeatureContext register(Object component, int priority);

335

FeatureContext register(Object component, Class<?>... contracts);

336

FeatureContext register(Object component, Map<Class<?>, Integer> contracts);

337

}

338

```

339

340

## Asynchronous Processing

341

342

### AsyncResponse Interface

343

344

Provides asynchronous response processing capabilities.

345

346

```java { .api }

347

public interface AsyncResponse {

348

349

boolean resume(Object response);

350

boolean resume(Throwable response);

351

352

boolean cancel();

353

boolean cancel(int retryAfter);

354

boolean cancel(Date retryAfter);

355

356

boolean isSuspended();

357

boolean isCancelled();

358

boolean isDone();

359

360

boolean setTimeout(long time, TimeUnit unit);

361

void setTimeoutHandler(TimeoutHandler handler);

362

363

Collection<Class<?>> register(Class<?> callback);

364

Map<Class<?>, Collection<Class<?>>> register(Class<?> callback, Class<?>... callbacks);

365

Collection<Class<?>> register(Object callback);

366

Map<Class<?>, Collection<Class<?>>> register(Object callback, Object... callbacks);

367

}

368

```

369

370

### @Suspended Annotation

371

372

Marks a parameter for AsyncResponse injection.

373

374

```java { .api }

375

@Target({ElementType.PARAMETER})

376

@Retention(RetentionPolicy.RUNTIME)

377

@Documented

378

public @interface Suspended {

379

}

380

```

381

382

**Asynchronous Processing Examples:**

383

384

```java

385

@Path("/async")

386

public class AsyncResource {

387

388

@Inject

389

private ExecutorService executorService;

390

391

// Simple async processing

392

@GET

393

@Path("/users/{id}")

394

public void getUser(@PathParam("id") String userId,

395

@Suspended AsyncResponse asyncResponse) {

396

397

executorService.submit(() -> {

398

try {

399

User user = userService.findById(userId);

400

asyncResponse.resume(user);

401

} catch (Exception e) {

402

asyncResponse.resume(e);

403

}

404

});

405

}

406

407

// Async with timeout

408

@GET

409

@Path("/expensive-operation")

410

public void expensiveOperation(@Suspended AsyncResponse asyncResponse) {

411

412

// Set 30 second timeout

413

asyncResponse.setTimeout(30, TimeUnit.SECONDS);

414

asyncResponse.setTimeoutHandler(ar ->

415

ar.resume(Response.status(Response.Status.REQUEST_TIMEOUT)

416

.entity("Operation timed out")

417

.build())

418

);

419

420

executorService.submit(() -> {

421

try {

422

String result = performExpensiveOperation();

423

asyncResponse.resume(Response.ok(result).build());

424

} catch (Exception e) {

425

asyncResponse.resume(Response.serverError()

426

.entity("Operation failed")

427

.build());

428

}

429

});

430

}

431

432

// Async with callbacks

433

@POST

434

@Path("/process")

435

public void processData(DataRequest request,

436

@Suspended AsyncResponse asyncResponse) {

437

438

// Register callbacks

439

asyncResponse.register(CompletionCallback.class);

440

asyncResponse.register(ConnectionCallback.class);

441

442

CompletableFuture.supplyAsync(() -> dataProcessor.process(request))

443

.thenAccept(asyncResponse::resume)

444

.exceptionally(throwable -> {

445

asyncResponse.resume(throwable);

446

return null;

447

});

448

}

449

}

450

```

451

452

### Completion and Connection Callbacks

453

454

```java { .api }

455

public interface CompletionCallback {

456

457

void onComplete(Throwable throwable);

458

}

459

460

public interface ConnectionCallback {

461

462

void onDisconnect(AsyncResponse disconnected);

463

}

464

```

465

466

### TimeoutHandler Interface

467

468

```java { .api }

469

public interface TimeoutHandler {

470

471

void handleTimeout(AsyncResponse asyncResponse);

472

}

473

```

474

475

**Callback Implementation Examples:**

476

477

```java

478

@Provider

479

public class AsyncCallbacks implements CompletionCallback, ConnectionCallback {

480

481

@Override

482

public void onComplete(Throwable throwable) {

483

if (throwable == null) {

484

System.out.println("Async operation completed successfully");

485

} else {

486

System.err.println("Async operation failed: " + throwable.getMessage());

487

}

488

}

489

490

@Override

491

public void onDisconnect(AsyncResponse disconnected) {

492

System.out.println("Client disconnected, cancelling operation");

493

// Cleanup resources, cancel background tasks, etc.

494

}

495

}

496

497

// Custom timeout handler

498

public class CustomTimeoutHandler implements TimeoutHandler {

499

500

@Override

501

public void handleTimeout(AsyncResponse asyncResponse) {

502

// Custom timeout response

503

ErrorResponse error = new ErrorResponse("TIMEOUT",

504

"Request processing timed out");

505

asyncResponse.resume(Response.status(Response.Status.REQUEST_TIMEOUT)

506

.entity(error)

507

.build());

508

}

509

}

510

```

511

512

## Resource Management

513

514

### ResourceContext Interface

515

516

Injectable helper for creating and initializing resource instances.

517

518

```java { .api }

519

public interface ResourceContext {

520

521

<T> T getResource(Class<T> resourceClass);

522

<T> T initResource(T resource);

523

}

524

```

525

526

### ResourceInfo Interface

527

528

Injectable interface providing runtime information about matched resource method.

529

530

```java { .api }

531

public interface ResourceInfo {

532

533

Method getResourceMethod();

534

Class<?> getResourceClass();

535

}

536

```

537

538

**Resource Management Examples:**

539

540

```java

541

@Path("/composite")

542

public class CompositeResource {

543

544

@Context

545

private ResourceContext resourceContext;

546

547

@GET

548

@Path("/user-orders/{userId}")

549

public Response getUserOrders(@PathParam("userId") String userId) {

550

551

// Get other resource instances

552

UserResource userResource = resourceContext.getResource(UserResource.class);

553

OrderResource orderResource = resourceContext.getResource(OrderResource.class);

554

555

// Use resources to build composite response

556

User user = userResource.getUser(userId);

557

List<Order> orders = orderResource.getUserOrders(userId);

558

559

UserOrdersResponse response = new UserOrdersResponse(user, orders);

560

return Response.ok(response).build();

561

}

562

}

563

564

// Resource info usage in filter

565

@Provider

566

public class ResourceInfoFilter implements ContainerRequestFilter {

567

568

@Context

569

private ResourceInfo resourceInfo;

570

571

@Override

572

public void filter(ContainerRequestContext requestContext) throws IOException {

573

Method method = resourceInfo.getResourceMethod();

574

Class<?> resourceClass = resourceInfo.getResourceClass();

575

576

System.out.println("Processing request for " +

577

resourceClass.getSimpleName() + "." + method.getName());

578

579

// Apply method-specific processing

580

if (method.isAnnotationPresent(Audited.class)) {

581

// Enable auditing for this request

582

requestContext.setProperty("audit.enabled", true);

583

}

584

}

585

}

586

```

587

588

## Name Binding

589

590

Name binding allows selective application of filters and interceptors.

591

592

**Name Binding Example:**

593

594

```java

595

// Define name binding annotation

596

@NameBinding

597

@Retention(RetentionPolicy.RUNTIME)

598

@Target({ElementType.TYPE, ElementType.METHOD})

599

public @interface Compress {

600

}

601

602

// Filter bound to @Compress annotation

603

@Provider

604

@Compress

605

public class CompressionFilter implements ContainerResponseFilter {

606

607

@Override

608

public void filter(ContainerRequestContext requestContext,

609

ContainerResponseContext responseContext) throws IOException {

610

611

String acceptEncoding = requestContext.getHeaderString("Accept-Encoding");

612

if (acceptEncoding != null && acceptEncoding.contains("gzip")) {

613

// Apply gzip compression

614

responseContext.getHeaders().add("Content-Encoding", "gzip");

615

// Wrap output stream with GZIPOutputStream

616

}

617

}

618

}

619

620

// Apply to specific methods

621

@Path("/data")

622

public class DataResource {

623

624

@GET

625

@Path("/large")

626

@Compress // Compression filter will be applied

627

public LargeDataSet getLargeData() {

628

return dataService.getLargeDataSet();

629

}

630

631

@GET

632

@Path("/small")

633

// No compression for small responses

634

public SmallData getSmallData() {

635

return dataService.getSmallData();

636

}

637

}

638

```

639

640

## Priority Constants

641

642

JAX-RS provides priority constants for ordering filters and interceptors.

643

644

```java { .api }

645

public final class Priorities {

646

647

public static final int AUTHENTICATION = 1000;

648

public static final int AUTHORIZATION = 2000;

649

public static final int HEADER_DECORATOR = 3000;

650

public static final int ENTITY_CODER = 4000;

651

public static final int USER = 5000;

652

}

653

```

654

655

**Priority Usage Example:**

656

657

```java

658

@Provider

659

@Priority(Priorities.AUTHENTICATION)

660

public class AuthenticationFilter implements ContainerRequestFilter {

661

// Executed first (lowest priority number)

662

}

663

664

@Provider

665

@Priority(Priorities.AUTHORIZATION)

666

public class AuthorizationFilter implements ContainerRequestFilter {

667

// Executed after authentication

668

}

669

670

@Provider

671

@Priority(Priorities.HEADER_DECORATOR)

672

public class HeaderDecoratorFilter implements ContainerResponseFilter {

673

// Executed for response processing

674

}

675

```