or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdconnection-management.mdcontext-resources.mdhandlers.mdindex.mdrequest-logging.mdrequest-response.mdsecurity-ssl.mdserver-core.mdsession-management.mdutility-handlers.md

context-resources.mddocs/

0

# Context and Resource Handling

1

2

Context and resource handling provides servlet-like contexts for organizing handlers, virtual host support, resource serving, and static content management.

3

4

## ContextHandler

5

6

The `ContextHandler` provides a servlet-like context for organizing request handling with path mapping, virtual hosts, and resource management.

7

8

```java { .api }

9

public class ContextHandler extends Handler.Wrapper implements Attributes, AliasCheck {

10

// Constructors

11

public ContextHandler();

12

public ContextHandler(String contextPath);

13

public ContextHandler(Handler handler, String contextPath);

14

15

// Context path configuration

16

public String getContextPath();

17

public void setContextPath(String contextPath);

18

public String getPathInContext(String canonicallyEncodedPath);

19

20

// Resource management

21

public Resource getBaseResource();

22

public void setBaseResource(Resource resource);

23

public void setResourceBase(String resourceBase);

24

public String getResourceBase();

25

26

// Virtual host support

27

public List<String> getVirtualHosts();

28

public void setVirtualHosts(String... vhosts);

29

public void addVirtualHosts(String... virtualHosts);

30

31

// Class loading

32

public ClassLoader getClassLoader();

33

public void setClassLoader(ClassLoader classLoader);

34

35

// MIME types

36

public MimeTypes getMimeTypes();

37

public void setMimeTypes(MimeTypes mimeTypes);

38

39

// Temporary directory

40

public File getTempDirectory();

41

public void setTempDirectory(File temp);

42

43

// Context initialization

44

public Map<String, String> getInitParams();

45

public String getInitParameter(String name);

46

public void setInitParameter(String name, String value);

47

48

// Display name

49

public String getDisplayName();

50

public void setDisplayName(String servletContextName);

51

52

// Alias checking

53

public boolean checkAlias(String pathInContext, Resource resource);

54

public void addAliasCheck(AliasCheck check);

55

public List<AliasCheck> getAliasChecks();

56

57

// Context availability

58

public boolean isAvailable();

59

public void setAvailable(boolean available);

60

public String getUnavailableException();

61

}

62

```

63

64

## Basic Context Usage

65

66

```java

67

// Create server

68

Server server = new Server(8080);

69

70

// Create context handler for /api

71

ContextHandler apiContext = new ContextHandler("/api");

72

apiContext.setHandler(new ApiHandler());

73

74

// Create context handler for /web

75

ContextHandler webContext = new ContextHandler("/web");

76

webContext.setResourceBase("src/main/webapp");

77

webContext.setHandler(new DefaultServlet()); // For static files

78

79

// Create context collection to route requests

80

ContextHandlerCollection contexts = new ContextHandlerCollection();

81

contexts.setHandlers(new Handler[]{apiContext, webContext});

82

83

server.setHandler(contexts);

84

```

85

86

## Advanced Context Configuration

87

88

```java

89

public class AdvancedContextSetup {

90

91

public void setupContexts(Server server) {

92

// Main application context

93

ContextHandler mainContext = createMainContext();

94

95

// Admin interface context

96

ContextHandler adminContext = createAdminContext();

97

98

// Static resources context

99

ContextHandler staticContext = createStaticContext();

100

101

// Combine contexts

102

ContextHandlerCollection contexts = new ContextHandlerCollection();

103

contexts.setHandlers(new Handler[]{

104

mainContext, adminContext, staticContext

105

});

106

107

server.setHandler(contexts);

108

}

109

110

private ContextHandler createMainContext() {

111

ContextHandler context = new ContextHandler("/app");

112

113

// Set display name

114

context.setDisplayName("Main Application");

115

116

// Configure resources

117

context.setResourceBase("src/main/webapp");

118

119

// Set initialization parameters

120

context.setInitParameter("debug", "true");

121

context.setInitParameter("environment", "development");

122

123

// Configure virtual hosts

124

context.setVirtualHosts(new String[]{"example.com", "www.example.com"});

125

126

// Set custom class loader

127

URLClassLoader customClassLoader = createCustomClassLoader();

128

context.setClassLoader(customClassLoader);

129

130

// Configure MIME types

131

MimeTypes mimeTypes = new MimeTypes();

132

mimeTypes.addMimeMapping("json", "application/json");

133

context.setMimeTypes(mimeTypes);

134

135

// Set temporary directory

136

context.setTempDirectory(new File("/tmp/jetty-main"));

137

138

// Add alias checks for security

139

context.addAliasCheck(new SymlinkAllowedResourceAliasChecker(context));

140

context.addAliasCheck(new AllowedResourceAliasChecker(context));

141

142

// Set handler

143

context.setHandler(new MainApplicationHandler());

144

145

return context;

146

}

147

148

private ContextHandler createAdminContext() {

149

ContextHandler context = new ContextHandler("/admin");

150

context.setDisplayName("Admin Interface");

151

152

// Restrict to localhost

153

context.setVirtualHosts(new String[]{"127.0.0.1", "localhost"});

154

155

// Admin-specific configuration

156

context.setInitParameter("adminMode", "true");

157

context.setHandler(new AdminHandler());

158

159

return context;

160

}

161

162

private ContextHandler createStaticContext() {

163

ContextHandler context = new ContextHandler("/static");

164

context.setDisplayName("Static Resources");

165

context.setResourceBase("static-content/");

166

167

// Use resource handler for static files

168

ResourceHandler resourceHandler = new ResourceHandler();

169

resourceHandler.setDirectoriesListed(false);

170

resourceHandler.setWelcomeFiles(new String[]{"index.html"});

171

172

context.setHandler(resourceHandler);

173

174

return context;

175

}

176

177

private URLClassLoader createCustomClassLoader() {

178

// Create custom class loader for context

179

return new URLClassLoader(new URL[]{}, getClass().getClassLoader());

180

}

181

}

182

```

183

184

## ContextHandlerCollection

185

186

Collection of context handlers with automatic routing based on context paths.

187

188

```java { .api }

189

public class ContextHandlerCollection extends Handler.Sequence {

190

// Context management

191

public ContextHandler[] getContextHandlers();

192

public void setContextHandlers(ContextHandler[] contextHandlers);

193

public void addContextHandler(ContextHandler contextHandler);

194

public boolean removeContextHandler(ContextHandler contextHandler);

195

196

// Context lookup

197

public ContextHandler getContextHandler(String contextPath);

198

public Map<String, ContextHandler> getContextHandlerMap();

199

200

// Request handling

201

public boolean handle(Request request, Response response, Callback callback) throws Exception;

202

}

203

```

204

205

## ResourceHandler

206

207

Specialized handler for serving static resources with caching, directory listing, and welcome files.

208

209

```java { .api }

210

public class ResourceHandler extends Handler.Wrapper {

211

// Resource configuration

212

public Resource getBaseResource();

213

public void setBaseResource(Resource baseResource);

214

public void setResourceBase(String resourceBase);

215

public String getResourceBase();

216

217

// Welcome files

218

public List<String> getWelcomeFiles();

219

public void setWelcomeFiles(String... welcomeFiles);

220

public void addWelcomeFiles(String... welcomeFiles);

221

222

// Directory listing

223

public boolean isDirectoriesListed();

224

public void setDirectoriesListed(boolean directoriesListed);

225

226

// Resource serving options

227

public boolean isAcceptRanges();

228

public void setAcceptRanges(boolean acceptRanges);

229

public boolean isEtags();

230

public void setEtags(boolean etags);

231

public int getCacheControl();

232

public void setCacheControl(int cacheControl);

233

234

// Resource service

235

public ResourceService getResourceService();

236

public void setResourceService(ResourceService resourceService);

237

238

// Path mapping

239

public String[] getPathInfoOnly();

240

public void setPathInfoOnly(String... pathInfoOnly);

241

}

242

```

243

244

## Resource Serving Examples

245

246

```java

247

public class StaticResourceServer {

248

249

public void setupStaticResources(Server server) {

250

// Create resource handler

251

ResourceHandler resourceHandler = new ResourceHandler();

252

253

// Configure base resource directory

254

resourceHandler.setResourceBase("src/main/webapp");

255

256

// Configure welcome files

257

resourceHandler.setWelcomeFiles(new String[]{

258

"index.html", "index.htm", "default.html"

259

});

260

261

// Enable directory listings for development

262

resourceHandler.setDirectoriesListed(true);

263

264

// Enable range requests for partial content

265

resourceHandler.setAcceptRanges(true);

266

267

// Enable ETags for caching

268

resourceHandler.setEtags(true);

269

270

// Set cache control (1 hour)

271

resourceHandler.setCacheControl(3600);

272

273

// Create context for static resources

274

ContextHandler staticContext = new ContextHandler("/static");

275

staticContext.setHandler(resourceHandler);

276

277

server.setHandler(staticContext);

278

}

279

}

280

```

281

282

### Advanced Resource Configuration

283

284

```java

285

public class AdvancedResourceHandler extends ResourceHandler {

286

287

@Override

288

protected void doStart() throws Exception {

289

super.doStart();

290

291

// Custom resource service configuration

292

ResourceService service = getResourceService();

293

294

// Configure caching

295

service.setAcceptRanges(true);

296

service.setDirAllowed(false); // Disable directory access

297

service.setRedirectWelcome(true); // Redirect to welcome files

298

service.setGzipEquivalentFileExtensions(Arrays.asList(".gz"));

299

300

// Custom welcome file resolution

301

service.setWelcomeFactory(this::findWelcomeFile);

302

}

303

304

private String findWelcomeFile(String pathInContext) {

305

// Custom logic to find welcome files

306

Resource resource = getBaseResource().resolve(pathInContext);

307

if (resource.isDirectory()) {

308

// Try different welcome files based on context

309

if (pathInContext.startsWith("/api")) {

310

return "api-index.html";

311

} else if (pathInContext.startsWith("/docs")) {

312

return "documentation.html";

313

}

314

}

315

return null; // Use default welcome files

316

}

317

318

@Override

319

public boolean handle(Request request, Response response, Callback callback)

320

throws Exception {

321

322

// Add custom headers for all resources

323

String path = request.getHttpURI().getPath();

324

325

if (path.endsWith(".css")) {

326

response.getHeaders().add("Content-Type", "text/css; charset=utf-8");

327

} else if (path.endsWith(".js")) {

328

response.getHeaders().add("Content-Type", "application/javascript; charset=utf-8");

329

}

330

331

// Add CORS headers for API resources

332

if (path.startsWith("/api")) {

333

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

334

}

335

336

return super.handle(request, response, callback);

337

}

338

}

339

```

340

341

## Resource Interface

342

343

The `Resource` interface provides abstraction for accessing files, directories, and other resources.

344

345

```java { .api }

346

public interface Resource {

347

// Resource identification

348

String getName();

349

URI getURI();

350

Path getPath();

351

352

// Resource state

353

boolean exists();

354

boolean isDirectory();

355

boolean isReadable();

356

long length();

357

long lastModified();

358

359

// Content access

360

InputStream newInputStream() throws IOException;

361

ReadableByteChannel newReadableByteChannel() throws IOException;

362

363

// Directory operations

364

List<Resource> list();

365

Resource resolve(String subPath);

366

367

// Resource creation

368

static Resource newResource(String resource);

369

static Resource newResource(URI uri);

370

static Resource newResource(Path path);

371

}

372

```

373

374

## Context Request and Response

375

376

### ContextRequest

377

378

Context-specific request wrapper providing additional context information.

379

380

```java { .api }

381

public class ContextRequest extends Request.Wrapper implements Invocable {

382

// Context information

383

public ContextHandler getContextHandler();

384

public Context getContext();

385

public String getContextPath();

386

public String getPathInContext();

387

388

// Session management

389

public HttpSession getSession();

390

public HttpSession getSession(boolean create);

391

392

// Attributes with context scope

393

public Object getAttribute(String name);

394

public void setAttribute(String name, Object value);

395

public void removeAttribute(String name);

396

public Set<String> getAttributeNameSet();

397

398

// Request dispatcher

399

public RequestDispatcher getRequestDispatcher(String path);

400

}

401

```

402

403

### ContextResponse

404

405

Context-specific response wrapper.

406

407

```java { .api }

408

public class ContextResponse extends Response.Wrapper {

409

// Response encoding

410

public void setCharacterEncoding(String encoding);

411

public String getCharacterEncoding();

412

public void setContentType(String contentType);

413

public String getContentType();

414

415

// Output handling

416

public PrintWriter getWriter() throws IOException;

417

public ServletOutputStream getOutputStream() throws IOException;

418

}

419

```

420

421

## Virtual Host Configuration

422

423

```java

424

public class VirtualHostExample {

425

426

public void setupVirtualHosts(Server server) {

427

// Context for main site

428

ContextHandler mainSite = new ContextHandler("/");

429

mainSite.setVirtualHosts(new String[]{"example.com", "www.example.com"});

430

mainSite.setHandler(new MainSiteHandler());

431

432

// Context for API subdomain

433

ContextHandler apiSite = new ContextHandler("/");

434

apiSite.setVirtualHosts(new String[]{"api.example.com"});

435

apiSite.setHandler(new ApiHandler());

436

437

// Context for admin subdomain with IP restriction

438

ContextHandler adminSite = new ContextHandler("/");

439

adminSite.setVirtualHosts(new String[]{"admin.example.com", "127.0.0.1:8080"});

440

adminSite.setHandler(new AdminHandler());

441

442

// Context for mobile site

443

ContextHandler mobileSite = new ContextHandler("/");

444

mobileSite.setVirtualHosts(new String[]{"m.example.com", "mobile.example.com"});

445

mobileSite.setHandler(new MobileSiteHandler());

446

447

// Combine all contexts

448

ContextHandlerCollection contexts = new ContextHandlerCollection();

449

contexts.setHandlers(new Handler[]{

450

mainSite, apiSite, adminSite, mobileSite

451

});

452

453

server.setHandler(contexts);

454

}

455

}

456

```

457

458

## Alias Checking and Security

459

460

### AliasCheck Interface

461

462

```java { .api }

463

public interface AliasCheck {

464

boolean checkAlias(String pathInContext, Resource resource);

465

}

466

```

467

468

### Built-in Alias Checkers

469

470

```java { .api }

471

public class AllowedResourceAliasChecker extends AbstractLifeCycle implements AliasCheck {

472

public AllowedResourceAliasChecker(ContextHandler contextHandler);

473

public boolean checkAlias(String pathInContext, Resource resource);

474

protected boolean check(String pathInContext, Resource resource);

475

}

476

477

public class SymlinkAllowedResourceAliasChecker extends AllowedResourceAliasChecker {

478

public SymlinkAllowedResourceAliasChecker(ContextHandler contextHandler);

479

}

480

```

481

482

### Custom Alias Checker

483

484

```java

485

public class SecurityAliasChecker implements AliasCheck {

486

private final Set<String> allowedExtensions;

487

private final Set<String> blockedPaths;

488

489

public SecurityAliasChecker() {

490

this.allowedExtensions = Set.of(".html", ".css", ".js", ".png", ".jpg", ".gif");

491

this.blockedPaths = Set.of("/WEB-INF", "/META-INF", "/.git", "/.svn");

492

}

493

494

@Override

495

public boolean checkAlias(String pathInContext, Resource resource) {

496

// Block access to sensitive directories

497

for (String blockedPath : blockedPaths) {

498

if (pathInContext.startsWith(blockedPath)) {

499

return false;

500

}

501

}

502

503

// Only allow specific file extensions

504

String fileName = resource.getName();

505

if (fileName != null) {

506

for (String ext : allowedExtensions) {

507

if (fileName.endsWith(ext)) {

508

return true;

509

}

510

}

511

}

512

513

return false; // Deny by default

514

}

515

}

516

517

// Usage

518

ContextHandler context = new ContextHandler("/files");

519

context.addAliasCheck(new SecurityAliasChecker());

520

```

521

522

## Context Initialization

523

524

```java

525

public class ContextInitializationExample extends ContextHandler {

526

527

@Override

528

protected void doStart() throws Exception {

529

// Pre-initialization

530

setupLogging();

531

loadConfiguration();

532

533

super.doStart();

534

535

// Post-initialization

536

initializeServices();

537

registerMBeans();

538

}

539

540

@Override

541

protected void doStop() throws Exception {

542

// Pre-shutdown

543

unregisterMBeans();

544

shutdownServices();

545

546

super.doStop();

547

548

// Post-shutdown

549

cleanupResources();

550

}

551

552

private void setupLogging() {

553

// Configure logging for this context

554

setAttribute("logLevel", "DEBUG");

555

}

556

557

private void loadConfiguration() {

558

// Load context-specific configuration

559

Properties config = new Properties();

560

try (InputStream is = getClass().getResourceAsStream("/context.properties")) {

561

if (is != null) {

562

config.load(is);

563

for (String key : config.stringPropertyNames()) {

564

setInitParameter(key, config.getProperty(key));

565

}

566

}

567

} catch (IOException e) {

568

throw new RuntimeException("Failed to load configuration", e);

569

}

570

}

571

572

private void initializeServices() {

573

// Initialize context-specific services

574

Object service = new MyContextService();

575

setAttribute("contextService", service);

576

}

577

578

private void registerMBeans() {

579

// Register JMX MBeans for monitoring

580

}

581

582

private void unregisterMBeans() {

583

// Unregister JMX MBeans

584

}

585

586

private void shutdownServices() {

587

// Shutdown services gracefully

588

Object service = getAttribute("contextService");

589

if (service instanceof MyContextService) {

590

((MyContextService) service).shutdown();

591

}

592

}

593

594

private void cleanupResources() {

595

// Final cleanup

596

}

597

}

598

```