or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

error-handling.mdframework-configuration.mdhttp-caching.mdindex.mdjsr310-parameters.mdoptional-handling.mdparameter-handling.mdsession-management.mdvalidation.md

session-management.mddocs/

0

# Session Management

1

2

HTTP session integration with injection support and flash message capabilities for web applications requiring session state. Provides seamless access to HttpSession objects and flash messaging functionality in JAX-RS resource methods.

3

4

## Capabilities

5

6

### Session Annotation

7

8

Annotation for injecting HttpSession instances into JAX-RS resource method parameters and fields.

9

10

```java { .api }

11

/**

12

* Injects HttpSession into resource method parameters or fields

13

* Supports configuration for session creation behavior

14

*/

15

@Documented

16

@Retention(RetentionPolicy.RUNTIME)

17

@Target({ElementType.PARAMETER, ElementType.FIELD})

18

public @interface Session {

19

20

/**

21

* Whether to avoid creating a new session if one doesn't exist

22

* @return true to avoid creating new sessions, false to create if needed

23

*/

24

boolean doNotCreate() default false;

25

}

26

```

27

28

**Usage Examples:**

29

30

```java

31

import io.dropwizard.jersey.sessions.Session;

32

import jakarta.servlet.http.HttpSession;

33

import jakarta.ws.rs.*;

34

35

@Path("/users")

36

public class UserResource {

37

38

@POST

39

@Path("/login")

40

public Response login(@FormParam("username") String username,

41

@FormParam("password") String password,

42

@Session HttpSession session) {

43

if (authService.authenticate(username, password)) {

44

session.setAttribute("userId", username);

45

session.setAttribute("loginTime", System.currentTimeMillis());

46

return Response.ok().build();

47

}

48

return Response.status(401).build();

49

}

50

51

@GET

52

@Path("/profile")

53

public UserProfile getProfile(@Session HttpSession session) {

54

String userId = (String) session.getAttribute("userId");

55

if (userId == null) {

56

throw new WebApplicationException(401);

57

}

58

return userService.getProfile(userId);

59

}

60

61

@POST

62

@Path("/logout")

63

public Response logout(@Session HttpSession session) {

64

session.invalidate();

65

return Response.ok().build();

66

}

67

68

// Don't create session if it doesn't exist

69

@GET

70

@Path("/check")

71

public Response checkSession(@Session(doNotCreate = true) HttpSession session) {

72

if (session == null) {

73

return Response.status(401).entity("No active session").build();

74

}

75

return Response.ok().entity("Session active").build();

76

}

77

}

78

```

79

80

### Flash Messages

81

82

Flash message support for storing temporary messages in the session that are automatically removed after being accessed.

83

84

```java { .api }

85

/**

86

* Flash message container for session-based temporary messages

87

* Messages are automatically removed after being accessed

88

* @param <T> type of flash message content

89

*/

90

public class Flash<T> {

91

92

/**

93

* Gets the flash message content, removing it from session

94

* @return Optional containing the flash message, or empty if none exists

95

*/

96

public Optional<T> get();

97

98

/**

99

* Sets a flash message in the session

100

* @param value the message content to store

101

*/

102

public void set(T value);

103

}

104

```

105

106

**Usage Examples:**

107

108

```java

109

import io.dropwizard.jersey.sessions.Flash;

110

import io.dropwizard.jersey.sessions.Session;

111

import jakarta.servlet.http.HttpSession;

112

import jakarta.ws.rs.*;

113

import java.util.Optional;

114

115

@Path("/account")

116

public class AccountResource {

117

118

@POST

119

@Path("/update")

120

public Response updateAccount(@Valid UpdateAccountRequest request,

121

@Session HttpSession session,

122

@Session Flash<String> flash) {

123

try {

124

accountService.update(getCurrentUserId(session), request);

125

flash.set("Account updated successfully!");

126

return Response.seeOther(URI.create("/account")).build();

127

} catch (ValidationException e) {

128

flash.set("Error: " + e.getMessage());

129

return Response.seeOther(URI.create("/account/edit")).build();

130

}

131

}

132

133

@GET

134

@Path("/")

135

public AccountView getAccount(@Session HttpSession session,

136

@Session Flash<String> flash) {

137

String userId = getCurrentUserId(session);

138

Account account = accountService.getAccount(userId);

139

140

// Check for flash message

141

Optional<String> message = flash.get(); // Automatically removes from session

142

143

return new AccountView(account, message.orElse(null));

144

}

145

146

@GET

147

@Path("/notifications")

148

public Response getNotifications(@Session Flash<List<String>> notifications) {

149

Optional<List<String>> messages = notifications.get();

150

if (messages.isPresent()) {

151

return Response.ok(messages.get()).build();

152

}

153

return Response.ok(Collections.emptyList()).build();

154

}

155

}

156

```

157

158

### Session Factories

159

160

Factory classes that provide HttpSession and Flash instances for dependency injection.

161

162

```java { .api }

163

/**

164

* Factory for creating HttpSession instances

165

* Used by Jersey's dependency injection system

166

*/

167

public class HttpSessionFactory implements Factory<HttpSession> {

168

169

/** Provides the current HttpSession instance */

170

public HttpSession provide();

171

172

/** Disposes of the HttpSession (no-op) */

173

public void dispose(HttpSession instance);

174

}

175

176

/**

177

* Factory for creating Flash instances

178

* Used by Jersey's dependency injection system

179

*/

180

public class FlashFactory implements Factory<Flash<?>> {

181

182

/** Provides a Flash instance for the current session */

183

public Flash<?> provide();

184

185

/** Disposes of the Flash instance (no-op) */

186

public void dispose(Flash<?> instance);

187

}

188

189

/**

190

* Provider that registers session-related factories with Jersey

191

*/

192

public class SessionFactoryProvider {

193

194

/**

195

* Binder that registers HttpSessionFactory and FlashFactory

196

* Used internally by DropwizardResourceConfig

197

*/

198

public static class Binder extends AbstractBinder {

199

protected void configure();

200

}

201

}

202

```

203

204

## Session Configuration

205

206

### Basic Session Setup

207

208

Sessions are automatically configured when using DropwizardResourceConfig, but you can customize session behavior:

209

210

```java

211

import io.dropwizard.jersey.DropwizardResourceConfig;

212

import io.dropwizard.jersey.sessions.SessionFactoryProvider;

213

214

public class MyApplication extends Application<MyConfiguration> {

215

216

@Override

217

public void run(MyConfiguration config, Environment environment) {

218

// Sessions are automatically registered with DropwizardResourceConfig

219

JerseyEnvironment jersey = environment.jersey();

220

221

// Register resources that use sessions

222

jersey.register(UserSessionResource.class);

223

224

// Configure session timeout in Jetty (if needed)

225

environment.servlets()

226

.setSessionHandler(new SessionHandler())

227

.getSessionManager()

228

.setMaxInactiveInterval(3600); // 1 hour

229

}

230

}

231

```

232

233

### Session Lifecycle Management

234

235

```java

236

@Path("/session")

237

public class SessionResource {

238

239

@POST

240

@Path("/create")

241

public Response createSession(@Session HttpSession session) {

242

// Session is automatically created if it doesn't exist

243

session.setAttribute("created", Instant.now());

244

return Response.ok().build();

245

}

246

247

@GET

248

@Path("/info")

249

public SessionInfo getSessionInfo(@Session HttpSession session) {

250

return SessionInfo.builder()

251

.id(session.getId())

252

.creationTime(Instant.ofEpochMilli(session.getCreationTime()))

253

.lastAccessTime(Instant.ofEpochMilli(session.getLastAccessedTime()))

254

.maxInactiveInterval(session.getMaxInactiveInterval())

255

.isNew(session.isNew())

256

.build();

257

}

258

259

@DELETE

260

@Path("/")

261

public Response invalidateSession(@Session HttpSession session) {

262

session.invalidate();

263

return Response.noContent().build();

264

}

265

}

266

```

267

268

### Flash Message Patterns

269

270

```java

271

@Path("/wizard")

272

public class WizardResource {

273

274

@POST

275

@Path("/step1")

276

public Response processStep1(@Valid Step1Data data,

277

@Session HttpSession session,

278

@Session Flash<WizardState> wizardFlash) {

279

// Store intermediate data in flash

280

WizardState state = new WizardState();

281

state.setStep1Data(data);

282

wizardFlash.set(state);

283

284

return Response.seeOther(URI.create("/wizard/step2")).build();

285

}

286

287

@GET

288

@Path("/step2")

289

public Step2View showStep2(@Session Flash<WizardState> wizardFlash) {

290

Optional<WizardState> state = wizardFlash.get();

291

if (!state.isPresent()) {

292

// No flash data, redirect to start

293

throw new WebApplicationException(

294

Response.seeOther(URI.create("/wizard/step1")).build()

295

);

296

}

297

298

return new Step2View(state.get().getStep1Data());

299

}

300

301

@POST

302

@Path("/step2")

303

public Response processStep2(@Valid Step2Data data,

304

@Session Flash<WizardState> wizardFlash) {

305

Optional<WizardState> state = wizardFlash.get();

306

if (!state.isPresent()) {

307

return Response.seeOther(URI.create("/wizard/step1")).build();

308

}

309

310

// Complete wizard with both steps

311

WizardResult result = wizardService.complete(

312

state.get().getStep1Data(),

313

data

314

);

315

316

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

317

}

318

}

319

```

320

321

## Best Practices

322

323

### Session Security

324

325

```java

326

@Path("/secure")

327

public class SecureResource {

328

329

@GET

330

@Path("/data")

331

public SecureData getData(@Session HttpSession session) {

332

// Always validate session state

333

String userId = (String) session.getAttribute("userId");

334

if (userId == null) {

335

throw new WebApplicationException(Response.Status.UNAUTHORIZED);

336

}

337

338

// Check session timeout

339

long lastAccess = session.getLastAccessedTime();

340

long now = System.currentTimeMillis();

341

if (now - lastAccess > TimeUnit.HOURS.toMillis(1)) {

342

session.invalidate();

343

throw new WebApplicationException(Response.Status.UNAUTHORIZED);

344

}

345

346

return secureService.getData(userId);

347

}

348

}

349

```

350

351

### Flash Message Types

352

353

```java

354

// Typed flash messages for type safety

355

@Session Flash<String> stringMessage;

356

@Session Flash<List<ValidationError>> validationErrors;

357

@Session Flash<UserNotification> notification;

358

@Session Flash<Map<String, Object>> formData;

359

360

// Generic flash for flexible content

361

@Session Flash<Object> genericFlash;

362

```

363

364

### Session vs Flash Usage

365

366

```java

367

public class SessionUsageExample {

368

369

// Use session attributes for persistent user state

370

public void storeUserPreferences(@Session HttpSession session, UserPreferences prefs) {

371

session.setAttribute("preferences", prefs);

372

session.setAttribute("theme", prefs.getTheme());

373

}

374

375

// Use flash messages for temporary notifications

376

public void showSuccessMessage(@Session Flash<String> flash) {

377

flash.set("Operation completed successfully!");

378

}

379

380

// Use flash for form data preservation on validation errors

381

public void preserveFormData(@Session Flash<FormData> flash, FormData data) {

382

flash.set(data); // Available for next request only

383

}

384

}

385

```