0
# Session Management and Cookies
1
2
The Java Servlet API provides comprehensive support for HTTP session management and cookie handling. This includes session lifecycle management, various session tracking modes, cookie configuration, and security considerations for state management.
3
4
## HttpSession Interface
5
6
```java { .api }
7
/**
8
* Interface representing an HTTP session between a client and server.
9
* Provides a way to identify a user across multiple requests and store
10
* user-specific information across those requests.
11
*/
12
public interface HttpSession {
13
14
/**
15
* Get the time when this session was created (milliseconds since epoch).
16
*/
17
long getCreationTime();
18
19
/**
20
* Get the unique session identifier.
21
*/
22
String getId();
23
24
/**
25
* Get the last time the client sent a request with this session ID.
26
*/
27
long getLastAccessedTime();
28
29
/**
30
* Get the servlet context for this session.
31
*/
32
ServletContext getServletContext();
33
34
/**
35
* Set the maximum time interval (seconds) between client requests
36
* before the session is invalidated.
37
*/
38
void setMaxInactiveInterval(int interval);
39
40
/**
41
* Get the maximum time interval (seconds) between client requests
42
* before the session is invalidated.
43
*/
44
int getMaxInactiveInterval();
45
46
/**
47
* Get the session context (deprecated).
48
*/
49
@Deprecated
50
HttpSessionContext getSessionContext();
51
52
/**
53
* Get the value of an attribute stored in this session.
54
*/
55
Object getAttribute(String name);
56
57
/**
58
* Get the value of an attribute (deprecated).
59
*/
60
@Deprecated
61
Object getValue(String name);
62
63
/**
64
* Get an enumeration of all attribute names in this session.
65
*/
66
Enumeration<String> getAttributeNames();
67
68
/**
69
* Get all attribute names (deprecated).
70
*/
71
@Deprecated
72
String[] getValueNames();
73
74
/**
75
* Store an attribute in this session.
76
*/
77
void setAttribute(String name, Object value);
78
79
/**
80
* Store a value in this session (deprecated).
81
*/
82
@Deprecated
83
void putValue(String name, Object value);
84
85
/**
86
* Remove an attribute from this session.
87
*/
88
void removeAttribute(String name);
89
90
/**
91
* Remove a value from this session (deprecated).
92
*/
93
@Deprecated
94
void removeValue(String name);
95
96
/**
97
* Invalidate this session and unbind all objects stored in it.
98
*/
99
void invalidate();
100
101
/**
102
* Check if this session is new (client hasn't acknowledged it yet).
103
*/
104
boolean isNew();
105
}
106
```
107
108
## Cookie Class
109
110
```java { .api }
111
/**
112
* Class representing an HTTP cookie.
113
* Implements Cloneable and Serializable for cookie management.
114
*/
115
public class Cookie implements Cloneable, Serializable {
116
117
private String name;
118
private String value;
119
private String comment;
120
private String domain;
121
private int maxAge = -1;
122
private String path;
123
private boolean secure;
124
private int version = 0;
125
private boolean httpOnly = false;
126
127
/**
128
* Create a cookie with the specified name and value.
129
*/
130
public Cookie(String name, String value) {
131
if (name == null || name.length() == 0) {
132
throw new IllegalArgumentException("Cookie name cannot be null or empty");
133
}
134
this.name = name;
135
this.value = value;
136
}
137
138
/**
139
* Set the comment describing the purpose of this cookie.
140
*/
141
public void setComment(String purpose) {
142
comment = purpose;
143
}
144
145
/**
146
* Get the comment describing the purpose of this cookie.
147
*/
148
public String getComment() {
149
return comment;
150
}
151
152
/**
153
* Set the domain for which this cookie is valid.
154
*/
155
public void setDomain(String domain) {
156
this.domain = domain.toLowerCase();
157
}
158
159
/**
160
* Get the domain for which this cookie is valid.
161
*/
162
public String getDomain() {
163
return domain;
164
}
165
166
/**
167
* Set the maximum age of this cookie in seconds.
168
* -1 indicates the cookie will persist until browser shutdown.
169
* 0 deletes the cookie immediately.
170
*/
171
public void setMaxAge(int expiry) {
172
maxAge = expiry;
173
}
174
175
/**
176
* Get the maximum age of this cookie in seconds.
177
*/
178
public int getMaxAge() {
179
return maxAge;
180
}
181
182
/**
183
* Set the path on the server to which the browser returns this cookie.
184
*/
185
public void setPath(String uri) {
186
path = uri;
187
}
188
189
/**
190
* Get the path on the server to which the browser returns this cookie.
191
*/
192
public String getPath() {
193
return path;
194
}
195
196
/**
197
* Set whether this cookie should only be sent over secure connections.
198
*/
199
public void setSecure(boolean flag) {
200
secure = flag;
201
}
202
203
/**
204
* Check if this cookie should only be sent over secure connections.
205
*/
206
public boolean getSecure() {
207
return secure;
208
}
209
210
/**
211
* Get the name of this cookie.
212
*/
213
public String getName() {
214
return name;
215
}
216
217
/**
218
* Set the value of this cookie.
219
*/
220
public void setValue(String newValue) {
221
value = newValue;
222
}
223
224
/**
225
* Get the value of this cookie.
226
*/
227
public String getValue() {
228
return value;
229
}
230
231
/**
232
* Get the version of the cookie protocol this cookie uses.
233
*/
234
public int getVersion() {
235
return version;
236
}
237
238
/**
239
* Set the version of the cookie protocol this cookie uses.
240
*/
241
public void setVersion(int v) {
242
version = v;
243
}
244
245
/**
246
* Set whether this cookie is HTTP only (not accessible via JavaScript).
247
*/
248
public void setHttpOnly(boolean httpOnly) {
249
this.httpOnly = httpOnly;
250
}
251
252
/**
253
* Check if this cookie is HTTP only.
254
*/
255
public boolean isHttpOnly() {
256
return httpOnly;
257
}
258
259
/**
260
* Create a copy of this cookie.
261
*/
262
public Object clone() {
263
try {
264
return super.clone();
265
} catch (CloneNotSupportedException e) {
266
throw new RuntimeException(e.getMessage());
267
}
268
}
269
}
270
```
271
272
## Session Tracking Modes
273
274
```java { .api }
275
/**
276
* Enumeration of supported session tracking modes.
277
*/
278
public enum SessionTrackingMode {
279
280
/**
281
* Session tracking via HTTP cookies.
282
*/
283
COOKIE,
284
285
/**
286
* Session tracking via URL rewriting (appending session ID to URLs).
287
*/
288
URL,
289
290
/**
291
* Session tracking via SSL session ID.
292
*/
293
SSL
294
}
295
```
296
297
## SessionCookieConfig Interface
298
299
```java { .api }
300
/**
301
* Interface for configuring session cookies.
302
* Allows programmatic configuration of session cookie properties.
303
*/
304
public interface SessionCookieConfig {
305
306
/**
307
* Set the name for session cookies created by the associated ServletContext.
308
*/
309
void setName(String name);
310
311
/**
312
* Get the name for session cookies.
313
*/
314
String getName();
315
316
/**
317
* Set the domain for session cookies.
318
*/
319
void setDomain(String domain);
320
321
/**
322
* Get the domain for session cookies.
323
*/
324
String getDomain();
325
326
/**
327
* Set the path for session cookies.
328
*/
329
void setPath(String path);
330
331
/**
332
* Get the path for session cookies.
333
*/
334
String getPath();
335
336
/**
337
* Set the comment for session cookies.
338
*/
339
void setComment(String comment);
340
341
/**
342
* Get the comment for session cookies.
343
*/
344
String getComment();
345
346
/**
347
* Set whether session cookies should be HTTP only.
348
*/
349
void setHttpOnly(boolean httpOnly);
350
351
/**
352
* Check if session cookies are HTTP only.
353
*/
354
boolean isHttpOnly();
355
356
/**
357
* Set whether session cookies should be secure (HTTPS only).
358
*/
359
void setSecure(boolean secure);
360
361
/**
362
* Check if session cookies are secure.
363
*/
364
boolean isSecure();
365
366
/**
367
* Set the maximum age for session cookies.
368
*/
369
void setMaxAge(int maxAge);
370
371
/**
372
* Get the maximum age for session cookies.
373
*/
374
int getMaxAge();
375
}
376
```
377
378
## Session Management Examples
379
380
### Basic Session Usage
381
382
```java { .api }
383
/**
384
* Servlet demonstrating basic session management
385
*/
386
@WebServlet("/session-demo")
387
public class SessionDemoServlet extends HttpServlet {
388
389
@Override
390
protected void doGet(HttpServletRequest request, HttpServletResponse response)
391
throws ServletException, IOException {
392
393
// Get or create session
394
HttpSession session = request.getSession();
395
396
// Get visit counter
397
Integer visitCount = (Integer) session.getAttribute("visitCount");
398
if (visitCount == null) {
399
visitCount = 0;
400
}
401
visitCount++;
402
403
// Store updated count
404
session.setAttribute("visitCount", visitCount);
405
session.setAttribute("lastVisit", new Date());
406
407
// Get user info if available
408
String username = (String) session.getAttribute("username");
409
410
response.setContentType("text/html;charset=UTF-8");
411
PrintWriter out = response.getWriter();
412
413
out.println("<!DOCTYPE html>");
414
out.println("<html>");
415
out.println("<head><title>Session Demo</title></head>");
416
out.println("<body>");
417
out.println("<h1>Session Information</h1>");
418
out.println("<p>Session ID: " + session.getId() + "</p>");
419
out.println("<p>Visit Count: " + visitCount + "</p>");
420
out.println("<p>Session Created: " + new Date(session.getCreationTime()) + "</p>");
421
out.println("<p>Last Accessed: " + new Date(session.getLastAccessedTime()) + "</p>");
422
out.println("<p>Max Inactive Interval: " + session.getMaxInactiveInterval() + " seconds</p>");
423
424
if (username != null) {
425
out.println("<p>Welcome back, " + username + "!</p>");
426
} else {
427
out.println("<p>You are not logged in.</p>");
428
out.println("<a href=\"/login\">Login</a>");
429
}
430
431
out.println("<p>Session Attributes:</p>");
432
out.println("<ul>");
433
Enumeration<String> attributeNames = session.getAttributeNames();
434
while (attributeNames.hasMoreElements()) {
435
String name = attributeNames.nextElement();
436
Object value = session.getAttribute(name);
437
out.println("<li>" + name + " = " + value + "</li>");
438
}
439
out.println("</ul>");
440
441
out.println("</body>");
442
out.println("</html>");
443
}
444
}
445
```
446
447
### Shopping Cart Session Example
448
449
```java { .api }
450
/**
451
* Shopping cart servlet using session storage
452
*/
453
@WebServlet("/cart/*")
454
public class ShoppingCartServlet extends HttpServlet {
455
456
@Override
457
protected void doGet(HttpServletRequest request, HttpServletResponse response)
458
throws ServletException, IOException {
459
460
String action = getAction(request);
461
HttpSession session = request.getSession();
462
463
switch (action) {
464
case "view":
465
viewCart(session, response);
466
break;
467
case "clear":
468
clearCart(session, response);
469
break;
470
default:
471
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid action");
472
}
473
}
474
475
@Override
476
protected void doPost(HttpServletRequest request, HttpServletResponse response)
477
throws ServletException, IOException {
478
479
String action = getAction(request);
480
HttpSession session = request.getSession();
481
482
switch (action) {
483
case "add":
484
addToCart(request, session, response);
485
break;
486
case "remove":
487
removeFromCart(request, session, response);
488
break;
489
case "update":
490
updateCartItem(request, session, response);
491
break;
492
default:
493
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid action");
494
}
495
}
496
497
private String getAction(HttpServletRequest request) {
498
String pathInfo = request.getPathInfo();
499
return pathInfo != null ? pathInfo.substring(1) : "view";
500
}
501
502
private void viewCart(HttpSession session, HttpServletResponse response)
503
throws IOException {
504
505
Map<String, CartItem> cart = getCart(session);
506
507
response.setContentType("application/json;charset=UTF-8");
508
PrintWriter out = response.getWriter();
509
510
out.println("{");
511
out.println(" \"sessionId\": \"" + session.getId() + "\",");
512
out.println(" \"itemCount\": " + cart.size() + ",");
513
out.println(" \"items\": [");
514
515
boolean first = true;
516
for (CartItem item : cart.values()) {
517
if (!first) out.println(",");
518
out.println(" {");
519
out.println(" \"productId\": \"" + item.getProductId() + "\",");
520
out.println(" \"name\": \"" + item.getName() + "\",");
521
out.println(" \"price\": " + item.getPrice() + ",");
522
out.println(" \"quantity\": " + item.getQuantity());
523
out.println(" }");
524
first = false;
525
}
526
527
out.println(" ],");
528
out.println(" \"total\": " + calculateTotal(cart));
529
out.println("}");
530
}
531
532
private void addToCart(HttpServletRequest request, HttpSession session,
533
HttpServletResponse response) throws IOException {
534
535
String productId = request.getParameter("productId");
536
String name = request.getParameter("name");
537
String priceStr = request.getParameter("price");
538
String quantityStr = request.getParameter("quantity");
539
540
if (productId == null || name == null || priceStr == null) {
541
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing parameters");
542
return;
543
}
544
545
try {
546
double price = Double.parseDouble(priceStr);
547
int quantity = quantityStr != null ? Integer.parseInt(quantityStr) : 1;
548
549
Map<String, CartItem> cart = getCart(session);
550
CartItem existingItem = cart.get(productId);
551
552
if (existingItem != null) {
553
existingItem.setQuantity(existingItem.getQuantity() + quantity);
554
} else {
555
cart.put(productId, new CartItem(productId, name, price, quantity));
556
}
557
558
response.setContentType("application/json;charset=UTF-8");
559
response.getWriter().write("{\"status\":\"success\",\"message\":\"Item added to cart\"}");
560
561
} catch (NumberFormatException e) {
562
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid number format");
563
}
564
}
565
566
private void removeFromCart(HttpServletRequest request, HttpSession session,
567
HttpServletResponse response) throws IOException {
568
569
String productId = request.getParameter("productId");
570
if (productId == null) {
571
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing productId");
572
return;
573
}
574
575
Map<String, CartItem> cart = getCart(session);
576
cart.remove(productId);
577
578
response.setContentType("application/json;charset=UTF-8");
579
response.getWriter().write("{\"status\":\"success\",\"message\":\"Item removed from cart\"}");
580
}
581
582
private void updateCartItem(HttpServletRequest request, HttpSession session,
583
HttpServletResponse response) throws IOException {
584
585
String productId = request.getParameter("productId");
586
String quantityStr = request.getParameter("quantity");
587
588
if (productId == null || quantityStr == null) {
589
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing parameters");
590
return;
591
}
592
593
try {
594
int quantity = Integer.parseInt(quantityStr);
595
Map<String, CartItem> cart = getCart(session);
596
CartItem item = cart.get(productId);
597
598
if (item != null) {
599
if (quantity <= 0) {
600
cart.remove(productId);
601
} else {
602
item.setQuantity(quantity);
603
}
604
}
605
606
response.setContentType("application/json;charset=UTF-8");
607
response.getWriter().write("{\"status\":\"success\",\"message\":\"Cart updated\"}");
608
609
} catch (NumberFormatException e) {
610
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid quantity");
611
}
612
}
613
614
private void clearCart(HttpSession session, HttpServletResponse response)
615
throws IOException {
616
617
session.removeAttribute("cart");
618
619
response.setContentType("application/json;charset=UTF-8");
620
response.getWriter().write("{\"status\":\"success\",\"message\":\"Cart cleared\"}");
621
}
622
623
@SuppressWarnings("unchecked")
624
private Map<String, CartItem> getCart(HttpSession session) {
625
Map<String, CartItem> cart = (Map<String, CartItem>) session.getAttribute("cart");
626
if (cart == null) {
627
cart = new ConcurrentHashMap<>();
628
session.setAttribute("cart", cart);
629
}
630
return cart;
631
}
632
633
private double calculateTotal(Map<String, CartItem> cart) {
634
return cart.values().stream()
635
.mapToDouble(item -> item.getPrice() * item.getQuantity())
636
.sum();
637
}
638
639
// Helper class for cart items
640
public static class CartItem implements Serializable {
641
private String productId;
642
private String name;
643
private double price;
644
private int quantity;
645
646
public CartItem(String productId, String name, double price, int quantity) {
647
this.productId = productId;
648
this.name = name;
649
this.price = price;
650
this.quantity = quantity;
651
}
652
653
// Getters and setters
654
public String getProductId() { return productId; }
655
public String getName() { return name; }
656
public double getPrice() { return price; }
657
public int getQuantity() { return quantity; }
658
public void setQuantity(int quantity) { this.quantity = quantity; }
659
}
660
}
661
```
662
663
### Cookie Management Examples
664
665
```java { .api }
666
/**
667
* Servlet demonstrating comprehensive cookie management
668
*/
669
@WebServlet("/cookie-manager")
670
public class CookieManagerServlet extends HttpServlet {
671
672
@Override
673
protected void doGet(HttpServletRequest request, HttpServletResponse response)
674
throws ServletException, IOException {
675
676
String action = request.getParameter("action");
677
678
switch (action != null ? action : "view") {
679
case "view":
680
viewCookies(request, response);
681
break;
682
case "set":
683
setCookie(request, response);
684
break;
685
case "delete":
686
deleteCookie(request, response);
687
break;
688
default:
689
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid action");
690
}
691
}
692
693
private void viewCookies(HttpServletRequest request, HttpServletResponse response)
694
throws IOException {
695
696
Cookie[] cookies = request.getCookies();
697
698
response.setContentType("application/json;charset=UTF-8");
699
PrintWriter out = response.getWriter();
700
701
out.println("{");
702
out.println(" \"cookies\": [");
703
704
if (cookies != null) {
705
for (int i = 0; i < cookies.length; i++) {
706
Cookie cookie = cookies[i];
707
if (i > 0) out.println(",");
708
709
out.println(" {");
710
out.println(" \"name\": \"" + cookie.getName() + "\",");
711
out.println(" \"value\": \"" + cookie.getValue() + "\",");
712
out.println(" \"domain\": \"" + cookie.getDomain() + "\",");
713
out.println(" \"path\": \"" + cookie.getPath() + "\",");
714
out.println(" \"maxAge\": " + cookie.getMaxAge() + ",");
715
out.println(" \"secure\": " + cookie.getSecure() + ",");
716
out.println(" \"httpOnly\": " + cookie.isHttpOnly() + ",");
717
out.println(" \"version\": " + cookie.getVersion());
718
out.println(" }");
719
}
720
}
721
722
out.println(" ]");
723
out.println("}");
724
}
725
726
private void setCookie(HttpServletRequest request, HttpServletResponse response)
727
throws IOException {
728
729
String name = request.getParameter("name");
730
String value = request.getParameter("value");
731
String domain = request.getParameter("domain");
732
String path = request.getParameter("path");
733
String maxAgeStr = request.getParameter("maxAge");
734
String secureStr = request.getParameter("secure");
735
String httpOnlyStr = request.getParameter("httpOnly");
736
737
if (name == null || value == null) {
738
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
739
"Cookie name and value are required");
740
return;
741
}
742
743
Cookie cookie = new Cookie(name, value);
744
745
// Set optional cookie properties
746
if (domain != null && !domain.isEmpty()) {
747
cookie.setDomain(domain);
748
}
749
750
if (path != null && !path.isEmpty()) {
751
cookie.setPath(path);
752
} else {
753
cookie.setPath("/"); // Default path
754
}
755
756
if (maxAgeStr != null && !maxAgeStr.isEmpty()) {
757
try {
758
int maxAge = Integer.parseInt(maxAgeStr);
759
cookie.setMaxAge(maxAge);
760
} catch (NumberFormatException e) {
761
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid maxAge");
762
return;
763
}
764
}
765
766
if ("true".equalsIgnoreCase(secureStr)) {
767
cookie.setSecure(true);
768
}
769
770
if ("true".equalsIgnoreCase(httpOnlyStr)) {
771
cookie.setHttpOnly(true);
772
}
773
774
response.addCookie(cookie);
775
776
response.setContentType("application/json;charset=UTF-8");
777
response.getWriter().write("{\"status\":\"success\",\"message\":\"Cookie set\"}");
778
}
779
780
private void deleteCookie(HttpServletRequest request, HttpServletResponse response)
781
throws IOException {
782
783
String name = request.getParameter("name");
784
if (name == null) {
785
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Cookie name required");
786
return;
787
}
788
789
// Create a cookie with the same name and set maxAge to 0
790
Cookie deleteCookie = new Cookie(name, "");
791
deleteCookie.setMaxAge(0);
792
deleteCookie.setPath("/");
793
794
response.addCookie(deleteCookie);
795
796
response.setContentType("application/json;charset=UTF-8");
797
response.getWriter().write("{\"status\":\"success\",\"message\":\"Cookie deleted\"}");
798
}
799
}
800
```
801
802
### Session Configuration
803
804
```java { .api }
805
/**
806
* ServletContextListener for session configuration
807
*/
808
@WebListener
809
public class SessionConfigListener implements ServletContextListener {
810
811
@Override
812
public void contextInitialized(ServletContextEvent sce) {
813
ServletContext context = sce.getServletContext();
814
815
// Configure session tracking modes
816
Set<SessionTrackingMode> trackingModes = EnumSet.of(
817
SessionTrackingMode.COOKIE,
818
SessionTrackingMode.URL
819
);
820
context.setSessionTrackingModes(trackingModes);
821
822
// Configure session cookies
823
SessionCookieConfig cookieConfig = context.getSessionCookieConfig();
824
cookieConfig.setName("JSESSIONID");
825
cookieConfig.setHttpOnly(true);
826
cookieConfig.setSecure(true); // Use only over HTTPS
827
cookieConfig.setMaxAge(-1); // Session cookie (expires when browser closes)
828
cookieConfig.setPath(context.getContextPath());
829
cookieConfig.setComment("Session tracking cookie");
830
831
// Log configuration
832
System.out.println("Session configuration initialized:");
833
System.out.println(" Tracking modes: " + trackingModes);
834
System.out.println(" Cookie name: " + cookieConfig.getName());
835
System.out.println(" HTTP only: " + cookieConfig.isHttpOnly());
836
System.out.println(" Secure: " + cookieConfig.isSecure());
837
}
838
839
@Override
840
public void contextDestroyed(ServletContextEvent sce) {
841
// Cleanup if needed
842
}
843
}
844
```
845
846
### User Authentication and Session
847
848
```java { .api }
849
/**
850
* Login servlet demonstrating session-based authentication
851
*/
852
@WebServlet("/auth")
853
public class AuthServlet extends HttpServlet {
854
855
@Override
856
protected void doPost(HttpServletRequest request, HttpServletResponse response)
857
throws ServletException, IOException {
858
859
String action = request.getParameter("action");
860
861
switch (action != null ? action : "") {
862
case "login":
863
handleLogin(request, response);
864
break;
865
case "logout":
866
handleLogout(request, response);
867
break;
868
default:
869
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid action");
870
}
871
}
872
873
private void handleLogin(HttpServletRequest request, HttpServletResponse response)
874
throws IOException {
875
876
String username = request.getParameter("username");
877
String password = request.getParameter("password");
878
String rememberMe = request.getParameter("rememberMe");
879
880
if (username == null || password == null) {
881
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
882
"Username and password required");
883
return;
884
}
885
886
// Validate credentials (replace with real authentication)
887
if (isValidCredentials(username, password)) {
888
HttpSession session = request.getSession();
889
890
// Store user information in session
891
session.setAttribute("username", username);
892
session.setAttribute("loginTime", new Date());
893
session.setAttribute("authenticated", true);
894
895
// Set session timeout (30 minutes)
896
session.setMaxInactiveInterval(30 * 60);
897
898
// Handle "Remember Me" functionality with cookie
899
if ("true".equals(rememberMe)) {
900
String rememberToken = generateRememberToken(username);
901
902
Cookie rememberCookie = new Cookie("rememberToken", rememberToken);
903
rememberCookie.setMaxAge(7 * 24 * 60 * 60); // 7 days
904
rememberCookie.setPath("/");
905
rememberCookie.setHttpOnly(true);
906
rememberCookie.setSecure(request.isSecure());
907
908
response.addCookie(rememberCookie);
909
910
// Store token in database for validation
911
storeRememberToken(username, rememberToken);
912
}
913
914
response.setContentType("application/json;charset=UTF-8");
915
response.getWriter().write("{\"status\":\"success\",\"message\":\"Login successful\"}");
916
917
} else {
918
// Invalid credentials
919
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
920
response.setContentType("application/json;charset=UTF-8");
921
response.getWriter().write("{\"status\":\"error\",\"message\":\"Invalid credentials\"}");
922
}
923
}
924
925
private void handleLogout(HttpServletRequest request, HttpServletResponse response)
926
throws IOException {
927
928
HttpSession session = request.getSession(false);
929
if (session != null) {
930
// Clear remember me token if exists
931
String username = (String) session.getAttribute("username");
932
if (username != null) {
933
clearRememberToken(username);
934
}
935
936
session.invalidate();
937
}
938
939
// Clear remember me cookie
940
Cookie rememberCookie = new Cookie("rememberToken", "");
941
rememberCookie.setMaxAge(0);
942
rememberCookie.setPath("/");
943
response.addCookie(rememberCookie);
944
945
response.setContentType("application/json;charset=UTF-8");
946
response.getWriter().write("{\"status\":\"success\",\"message\":\"Logout successful\"}");
947
}
948
949
private boolean isValidCredentials(String username, String password) {
950
// Replace with real authentication logic
951
return "admin".equals(username) && "password".equals(password);
952
}
953
954
private String generateRememberToken(String username) {
955
// Generate secure random token
956
return UUID.randomUUID().toString() + "-" + System.currentTimeMillis();
957
}
958
959
private void storeRememberToken(String username, String token) {
960
// Store token in database with expiration
961
}
962
963
private void clearRememberToken(String username) {
964
// Remove token from database
965
}
966
}
967
```
968
969
This comprehensive coverage of session management and cookies provides all the tools needed for maintaining user state and implementing secure authentication systems in servlet applications.