or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

http-abstractions.mdhttp-clients.mdindex.mdmessage-conversion.mdreactive-web.mdweb-binding.mdweb-utilities.md

reactive-web.mddocs/

0

# Reactive Web Support

1

2

Non-blocking web server infrastructure for building reactive applications with WebFlux. Provides the foundation for reactive web programming with streaming data processing and backpressure support.

3

4

## Capabilities

5

6

### Core Reactive Web Interfaces

7

8

Fundamental interfaces for reactive web request/response handling and filtering.

9

10

```java { .api }

11

/**

12

* Contract to handle a web request reactively

13

*/

14

@FunctionalInterface

15

interface WebHandler {

16

/** Handle the web request and return a completion signal */

17

Mono<Void> handle(ServerWebExchange exchange);

18

}

19

20

/**

21

* Contract for HTTP request-response interaction in reactive environment

22

*/

23

interface ServerWebExchange {

24

/** Get the server HTTP request */

25

ServerHttpRequest getRequest();

26

/** Get the server HTTP response */

27

ServerHttpResponse getResponse();

28

29

/** Get exchange attributes */

30

Map<String, Object> getAttributes();

31

/** Get attribute value */

32

@Nullable

33

<T> T getAttribute(String name);

34

/** Get attribute with default value */

35

<T> T getAttributeOrDefault(String name, T defaultValue);

36

/** Get required attribute (throws if not present) */

37

<T> T getRequiredAttribute(String name);

38

39

/** Create a builder for mutating exchange properties */

40

ServerWebExchange.Builder mutate();

41

42

/** Check if response should not be modified based on request conditions */

43

boolean isNotModified();

44

/** Check not modified with last modified date */

45

boolean checkNotModified(Instant lastModified);

46

/** Check not modified with ETag */

47

boolean checkNotModified(String etag);

48

/** Check not modified with both ETag and last modified */

49

boolean checkNotModified(@Nullable String etag, Instant lastModified);

50

51

/** Transform URL (useful for proxies and gateways) */

52

String transformUrl(String url);

53

/** Add URL transformer */

54

void addUrlTransformer(Function<String, String> transformer);

55

56

/** Get authenticated principal */

57

<T extends Principal> Mono<T> getPrincipal();

58

/** Get web session */

59

Mono<WebSession> getSession();

60

/** Get form data */

61

Mono<MultiValueMap<String, String>> getFormData();

62

/** Get multipart data */

63

Mono<MultiValueMap<String, Part>> getMultipartData();

64

65

/** Get locale context */

66

LocaleContext getLocaleContext();

67

/** Get application context */

68

ApplicationContext getApplicationContext();

69

}

70

71

/**

72

* Contract for interception-style processing of web requests

73

*/

74

@FunctionalInterface

75

interface WebFilter {

76

/** Filter the request and delegate to the next filter or handler */

77

Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain);

78

}

79

80

/**

81

* Contract to allow WebFilter to delegate to the next in chain

82

*/

83

@FunctionalInterface

84

interface WebFilterChain {

85

/** Invoke the next filter in the chain or the handler */

86

Mono<Void> filter(ServerWebExchange exchange);

87

}

88

```

89

90

### Server HTTP Abstractions

91

92

Reactive server-side HTTP request and response abstractions with streaming support.

93

94

```java { .api }

95

/**

96

* Reactive server-side HTTP request

97

*/

98

interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage {

99

/** Get unique request ID */

100

String getId();

101

/** Get request path */

102

RequestPath getPath();

103

/** Get query parameters */

104

MultiValueMap<String, String> getQueryParams();

105

/** Get cookies */

106

MultiValueMap<String, HttpCookie> getCookies();

107

108

/** Get remote address */

109

@Nullable

110

InetSocketAddress getRemoteAddress();

111

/** Get local address */

112

@Nullable

113

InetSocketAddress getLocalAddress();

114

/** Get SSL info */

115

@Nullable

116

SslInfo getSslInfo();

117

118

/** Create builder for mutating request properties */

119

ServerHttpRequest.Builder mutate();

120

}

121

122

/**

123

* Reactive server-side HTTP response

124

*/

125

interface ServerHttpResponse extends ReactiveHttpOutputMessage {

126

/** Set response status code */

127

boolean setStatusCode(@Nullable HttpStatusCode status);

128

/** Get response status code */

129

@Nullable

130

HttpStatusCode getStatusCode();

131

132

/** Get response cookies */

133

MultiValueMap<String, ResponseCookie> getCookies();

134

/** Add response cookie */

135

void addCookie(ResponseCookie cookie);

136

}

137

138

/**

139

* Represents HTTP request path with segments and parameters

140

*/

141

interface RequestPath extends PathContainer {

142

/** Get full path value */

143

String value();

144

/** Get context path */

145

PathContainer contextPath();

146

/** Get path within application */

147

PathContainer pathWithinApplication();

148

149

/** Modify context path */

150

RequestPath modifyContextPath(String contextPath);

151

}

152

153

/**

154

* HTTP cookie representation

155

*/

156

class HttpCookie {

157

HttpCookie(String name, String value);

158

159

/** Get cookie name */

160

String getName();

161

/** Get cookie value */

162

String getValue();

163

}

164

165

/**

166

* Response cookie with additional attributes

167

*/

168

class ResponseCookie extends HttpCookie {

169

/** Get max age */

170

Duration getMaxAge();

171

/** Get domain */

172

@Nullable

173

String getDomain();

174

/** Get path */

175

@Nullable

176

String getPath();

177

/** Is secure flag set */

178

boolean isSecure();

179

/** Is HTTP only flag set */

180

boolean isHttpOnly();

181

/** Get SameSite attribute */

182

@Nullable

183

String getSameSite();

184

185

/** Create response cookie builder */

186

static ResponseCookieBuilder from(String name, String value);

187

static ResponseCookieBuilder fromClientResponse(String name, String value);

188

}

189

```

190

191

### Web Session Management

192

193

Reactive web session management with pluggable session stores.

194

195

```java { .api }

196

/**

197

* Main contract for using a server-side session

198

*/

199

interface WebSession {

200

/** Get unique session ID */

201

String getId();

202

/** Get session attributes */

203

Map<String, Object> getAttributes();

204

205

/** Start the session */

206

void start();

207

/** Check if session is started */

208

boolean isStarted();

209

/** Generate new session ID */

210

Mono<Void> changeSessionId();

211

/** Invalidate the session */

212

Mono<Void> invalidate();

213

/** Save session state */

214

Mono<Void> save();

215

216

/** Check if session is expired */

217

boolean isExpired();

218

/** Get session creation time */

219

Instant getCreationTime();

220

/** Get last access time */

221

Instant getLastAccessTime();

222

223

/** Set max idle time */

224

void setMaxIdleTime(Duration maxIdleTime);

225

/** Get max idle time */

226

Duration getMaxIdleTime();

227

}

228

229

/**

230

* Main class for WebSession access and management

231

*/

232

interface WebSessionManager {

233

/** Get session for the exchange */

234

Mono<WebSession> getSession(ServerWebExchange exchange);

235

}

236

237

/**

238

* Strategy for session ID resolution

239

*/

240

interface WebSessionIdResolver {

241

/** Resolve session IDs from request */

242

List<String> resolveSessionIds(ServerWebExchange exchange);

243

/** Set session ID in response */

244

void setSessionId(ServerWebExchange exchange, String sessionId);

245

/** Expire session ID */

246

void expireSession(ServerWebExchange exchange);

247

}

248

249

/**

250

* Strategy for WebSession persistence

251

*/

252

interface WebSessionStore {

253

/** Create a new session */

254

Mono<WebSession> createWebSession();

255

/** Retrieve session by ID */

256

Mono<WebSession> retrieveSession(String sessionId);

257

/** Remove session by ID */

258

Mono<Void> removeSession(String sessionId);

259

/** Update last access time */

260

Mono<WebSession> updateLastAccessTime(WebSession webSession);

261

}

262

```

263

264

### Exception Handling

265

266

Reactive web exception handling and error processing.

267

268

```java { .api }

269

/**

270

* Contract for handling exceptions during web exchange processing

271

*/

272

interface WebExceptionHandler {

273

/** Handle the exception and return completion signal */

274

Mono<Void> handle(ServerWebExchange exchange, Throwable ex);

275

}

276

277

/**

278

* WebExceptionHandler that can decorate the error with additional attributes

279

*/

280

interface ErrorWebExceptionHandler extends WebExceptionHandler {

281

// Marker interface for error-specific exception handlers

282

}

283

284

/**

285

* Exception thrown to trigger specific HTTP response status

286

*/

287

class ResponseStatusException extends NestedRuntimeException {

288

ResponseStatusException(HttpStatus status);

289

ResponseStatusException(HttpStatusCode status, String reason);

290

ResponseStatusException(HttpStatusCode status, String reason, Throwable cause);

291

292

/** Get HTTP status */

293

HttpStatusCode getStatusCode();

294

/** Get reason phrase */

295

String getReason();

296

}

297

298

/**

299

* Exception for method not supported

300

*/

301

class MethodNotAllowedException extends ResponseStatusException {

302

MethodNotAllowedException(HttpMethod method, Collection<HttpMethod> supportedMethods);

303

MethodNotAllowedException(String httpMethod, Collection<String> supportedMethods);

304

305

/** Get the unsupported method */

306

String getHttpMethod();

307

/** Get supported methods */

308

Set<String> getSupportedMethods();

309

}

310

311

/**

312

* Exception for unsupported media type

313

*/

314

class UnsupportedMediaTypeException extends ResponseStatusException {

315

UnsupportedMediaTypeException(String reason);

316

UnsupportedMediaTypeException(@Nullable MediaType contentType, List<MediaType> supportedTypes);

317

UnsupportedMediaTypeException(@Nullable MediaType contentType, List<MediaType> supportedTypes, ResolvableType bodyType);

318

319

/** Get the content type */

320

@Nullable

321

MediaType getContentType();

322

/** Get supported media types */

323

List<MediaType> getSupportedMediaTypes();

324

}

325

```

326

327

### Web Handler Builder

328

329

Builder for constructing reactive web handling pipeline with filters, exception handlers, and codecs.

330

331

```java { .api }

332

/**

333

* Builder for assembling reactive web handling processing pipeline

334

*/

335

class WebHttpHandlerBuilder {

336

/** Create builder with WebHandler */

337

static WebHttpHandlerBuilder webHandler(WebHandler webHandler);

338

/** Create builder from application context */

339

static WebHttpHandlerBuilder applicationContext(ApplicationContext context);

340

341

/** Add WebFilter instances */

342

WebHttpHandlerBuilder filter(WebFilter... filters);

343

/** Configure WebFilter list */

344

WebHttpHandlerBuilder filters(Consumer<List<WebFilter>> filtersConsumer);

345

346

/** Add WebExceptionHandler instances */

347

WebHttpHandlerBuilder exceptionHandler(WebExceptionHandler... handlers);

348

/** Configure WebExceptionHandler list */

349

WebHttpHandlerBuilder exceptionHandlers(Consumer<List<WebExceptionHandler>> handlersConsumer);

350

351

/** Configure message readers and writers */

352

WebHttpHandlerBuilder codecs(Consumer<ServerCodecConfigurer> codecsConsumer);

353

354

/** Set locale context resolver */

355

WebHttpHandlerBuilder localeContextResolver(LocaleContextResolver localeContextResolver);

356

/** Set forwarded header transformer */

357

WebHttpHandlerBuilder forwardedHeaderTransformer(ForwardedHeaderTransformer transformer);

358

359

/** Set WebSession manager */

360

WebHttpHandlerBuilder sessionManager(WebSessionManager sessionManager);

361

362

/** Build the HttpHandler */

363

HttpHandler build();

364

}

365

```

366

367

**Usage Examples:**

368

369

```java

370

// Build reactive web handler pipeline

371

HttpHandler handler = WebHttpHandlerBuilder

372

.webHandler(exchange -> {

373

ServerHttpResponse response = exchange.getResponse();

374

DataBuffer buffer = response.bufferFactory().wrap("Hello World".getBytes());

375

return response.writeWith(Mono.just(buffer));

376

})

377

.filter((exchange, chain) -> {

378

System.out.println("Request: " + exchange.getRequest().getPath());

379

return chain.filter(exchange);

380

})

381

.exceptionHandler((exchange, throwable) -> {

382

exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);

383

return exchange.getResponse().setComplete();

384

})

385

.build();

386

387

// Configure with application context

388

@Configuration

389

@EnableWebFlux

390

public class WebConfig {

391

392

@Bean

393

public HttpHandler httpHandler(ApplicationContext context) {

394

return WebHttpHandlerBuilder.applicationContext(context)

395

.filter(new CorsWebFilter(corsConfigurationSource()))

396

.exceptionHandler(new GlobalExceptionHandler())

397

.build();

398

}

399

}

400

```

401

402

### Server Web Exchange Implementation

403

404

Default implementation and builder for ServerWebExchange.

405

406

```java { .api }

407

/**

408

* Default implementation of ServerWebExchange

409

*/

410

class DefaultServerWebExchange implements ServerWebExchange {

411

DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,

412

WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,

413

LocaleContextResolver localeContextResolver);

414

415

// Implements all ServerWebExchange methods

416

}

417

418

/**

419

* Builder for mutating ServerWebExchange properties

420

*/

421

interface ServerWebExchange.Builder {

422

/** Override the request */

423

ServerWebExchange.Builder request(Consumer<ServerHttpRequest.Builder> requestBuilderConsumer);

424

/** Override the request directly */

425

ServerWebExchange.Builder request(ServerHttpRequest request);

426

427

/** Override the response */

428

ServerWebExchange.Builder response(ServerHttpResponse response);

429

430

/** Override principal */

431

ServerWebExchange.Builder principal(Mono<Principal> principalMono);

432

433

/** Build the mutated exchange */

434

ServerWebExchange build();

435

}

436

```

437

438

### Reactive Server Support Classes

439

440

Support classes for reactive web server implementations.

441

442

```java { .api }

443

/**

444

* HTTP handler adapter for different server implementations

445

*/

446

interface HttpHandler {

447

/** Handle HTTP request/response */

448

Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);

449

}

450

451

/**

452

* WebHandler adapter to HttpHandler

453

*/

454

class WebHandlerAdapter implements HttpHandler {

455

WebHandlerAdapter(WebHandler delegate);

456

457

/** Set web session manager */

458

void setSessionManager(WebSessionManager sessionManager);

459

/** Set codec configurer */

460

void setCodecConfigurer(ServerCodecConfigurer codecConfigurer);

461

/** Set locale context resolver */

462

void setLocaleContextResolver(LocaleContextResolver localeContextResolver);

463

/** Set forwarded header transformer */

464

void setForwardedHeaderTransformer(ForwardedHeaderTransformer transformer);

465

/** Set application context */

466

void setApplicationContext(ApplicationContext applicationContext);

467

468

Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);

469

}

470

471

/**

472

* Composite WebExceptionHandler

473

*/

474

class ExceptionHandlingWebHandler implements WebHandler {

475

ExceptionHandlingWebHandler(WebHandler delegate, WebExceptionHandler... handlers);

476

ExceptionHandlingWebHandler(WebHandler delegate, List<WebExceptionHandler> handlers);

477

478

Mono<Void> handle(ServerWebExchange exchange);

479

}

480

481

/**

482

* Composite WebFilter handler

483

*/

484

class FilteringWebHandler implements WebHandler {

485

FilteringWebHandler(WebHandler handler, WebFilter... filters);

486

FilteringWebHandler(WebHandler handler, List<WebFilter> filters);

487

488

Mono<Void> handle(ServerWebExchange exchange);

489

}

490

```

491

492

**Usage Examples:**

493

494

```java

495

// Custom WebHandler implementation

496

@Component

497

public class HelloWebHandler implements WebHandler {

498

499

@Override

500

public Mono<Void> handle(ServerWebExchange exchange) {

501

ServerHttpResponse response = exchange.getResponse();

502

response.getHeaders().add("Content-Type", "text/plain");

503

504

String message = "Hello, " + exchange.getRequest().getQueryParams().getFirst("name");

505

DataBuffer buffer = response.bufferFactory().wrap(message.getBytes());

506

507

return response.writeWith(Mono.just(buffer));

508

}

509

}

510

511

// Custom WebFilter implementation

512

@Component

513

public class LoggingWebFilter implements WebFilter {

514

515

private static final Logger logger = LoggerFactory.getLogger(LoggingWebFilter.class);

516

517

@Override

518

public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

519

long start = System.currentTimeMillis();

520

521

return chain.filter(exchange)

522

.doFinally(signalType -> {

523

long duration = System.currentTimeMillis() - start;

524

logger.info("Request {} {} completed in {}ms with status {}",

525

exchange.getRequest().getMethod(),

526

exchange.getRequest().getPath(),

527

duration,

528

exchange.getResponse().getStatusCode());

529

});

530

}

531

}

532

533

// Session handling example

534

@Component

535

public class SessionWebHandler implements WebHandler {

536

537

@Override

538

public Mono<Void> handle(ServerWebExchange exchange) {

539

return exchange.getSession()

540

.flatMap(session -> {

541

// Get or create visit count

542

Integer visitCount = session.getAttributes()

543

.compute("visitCount", (key, val) -> val == null ? 1 : (Integer) val + 1);

544

545

String message = "Visit count: " + visitCount;

546

DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(message.getBytes());

547

548

return exchange.getResponse().writeWith(Mono.just(buffer));

549

});

550

}

551

}

552

```

553

554

### Error Handling and Status Pages

555

556

Built-in support for error handling and status page generation.

557

558

```java { .api }

559

/**

560

* Default error WebExceptionHandler implementation

561

*/

562

class DefaultErrorWebExceptionHandler implements ErrorWebExceptionHandler, ApplicationContextAware {

563

DefaultErrorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties.Resources resources,

564

ApplicationContext applicationContext);

565

566

/** Set message writers for error response */

567

void setMessageWriters(List<HttpMessageWriter<?>> messageWriters);

568

/** Set view resolvers for error pages */

569

void setViewResolvers(List<ViewResolver> viewResolvers);

570

571

Mono<Void> handle(ServerWebExchange exchange, Throwable ex);

572

}

573

574

/**

575

* Error attributes for error information

576

*/

577

interface ErrorAttributes {

578

/** Get error attributes for the request */

579

Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options);

580

/** Get the error for the request */

581

Throwable getError(ServerRequest request);

582

/** Store error in request attributes */

583

void storeErrorInformation(Throwable error, ServerWebExchange exchange);

584

}

585

```

586

587

**Usage Examples:**

588

589

```java

590

// Custom exception handler

591

@Component

592

public class GlobalWebExceptionHandler implements WebExceptionHandler {

593

594

private final ObjectMapper objectMapper = new ObjectMapper();

595

596

@Override

597

public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {

598

ServerHttpResponse response = exchange.getResponse();

599

response.getHeaders().add("Content-Type", "application/json");

600

601

if (ex instanceof ResponseStatusException) {

602

ResponseStatusException rse = (ResponseStatusException) ex;

603

response.setStatusCode(rse.getStatusCode());

604

} else {

605

response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);

606

}

607

608

ErrorResponse error = new ErrorResponse(ex.getMessage(), System.currentTimeMillis());

609

610

try {

611

byte[] bytes = objectMapper.writeValueAsBytes(error);

612

DataBuffer buffer = response.bufferFactory().wrap(bytes);

613

return response.writeWith(Mono.just(buffer));

614

} catch (Exception e) {

615

return response.setComplete();

616

}

617

}

618

619

private static class ErrorResponse {

620

public final String message;

621

public final long timestamp;

622

623

ErrorResponse(String message, long timestamp) {

624

this.message = message;

625

this.timestamp = timestamp;

626

}

627

}

628

}

629

630

// Configuration for reactive web

631

@Configuration

632

@EnableWebFlux

633

public class ReactiveWebConfig implements WebFluxConfigurer {

634

635

@Bean

636

public WebExceptionHandler globalExceptionHandler() {

637

return new GlobalWebExceptionHandler();

638

}

639

640

@Bean

641

public CorsWebFilter corsWebFilter() {

642

CorsConfiguration corsConfig = new CorsConfiguration();

643

corsConfig.addAllowedOrigin("*");

644

corsConfig.addAllowedMethod("*");

645

corsConfig.addAllowedHeader("*");

646

647

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

648

source.registerCorsConfiguration("/**", corsConfig);

649

650

return new CorsWebFilter(source);

651

}

652

}

653

```