The session has not expired. The reason why the stored data is lost for no reason is that the session has expired.
Problem:
We often perform a function to save the login user information to the session and display the login user name on the page. However, if the page is not refreshed in a short period of time or even a few seconds, the user name disappears. In fact, the user data stored in the session is lost.
Baidu has a lot of problems, most of which say that the session expiration time is a little longer, or tomcat configuration problems, but none of them can be solved .... when I asked this question in my previous blog, I had a comments from my bloggers and I thought it was true that O (Taobao _ Taobao) O Haha ~ Thank you !!!
Then let's take a look at the test process.
The following is the user entity class:
1 package com. lizhou. entity; 2 3/** 4 * User class 5 * @ author bojiangzhou 6 * @ date February 28, 2016 7 */8 public class User {9 10 private int id; 11 12 private String name; 13 14 public User () {15 16} 17 18 public User (int id, String name) {19 this. id = id; 20 this. name = name; 21} 22 23 public int getId () {24 return id; 25} 26 27 public void setId (int id) {28 this. id = id; 29} 30 31 public String getName () {32 return name; 33} 34 35 public void setName (String name) {36 this. name = name; 37} 38 39}
User servlet: Enter http: // localhost: 8080/session/UserServlet in the address bar for access, and then redirect to showUser. jsp (this way, the servlet will not be accessed when the page is refreshed)
1 package com. lizhou. servlet; 2 3 import java. io. IOException; 4 import javax. servlet. servletException; 5 import javax. servlet. annotation. webServlet; 6 import javax. servlet. http. httpServlet; 7 import javax. servlet. http. httpServletRequest; 8 import javax. servlet. http. httpServletResponse; 9 10 import com. lizhou. entity. user; 11 12/** 13 * User servlet14 * @ author bojiangzhou15 * @ date February 28, 2016 16 */17 public class UserServlet extends HttpServlet {18 private static final long serialVersionUID = 1L; 19 20 protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {21 request. setCharacterEncoding ("UTF-8"); 22 23 User user = new User (); 24 user. setId (1); 25 user. setName ("Chiangchou"); 26 27 // Save User information to session 28 request. getSession (). setAttribute ("user", user); 29 // save a string 30 request. getSession (). setAttribute ("message", "User Logon successful"); 31 32 // redirect 33 response. sendRedirect ("showUser. jsp "); 34 35} 36 37 protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {38 39} 40 41}
Session listener: monitors the creation and destruction of sessions, adds properties to sessions, removes properties, and changes properties.
1 package com. lizhou. listener; 2 3 import javax. servlet. http. httpSessionAttributeListener; 4 import javax. servlet. http. httpSessionBindingEvent; 5 import javax. servlet. http. httpSessionEvent; 6 import javax. servlet. http. httpSessionListener; 7 8/** 9 * session listener 10 * @ author bojiangzhou11 * @ date February 28, 2016 12 */13 public class SessionListener implements HttpSessionListener, httpSessionAttributeListener {14 15 // attribute addition time 16 private long addTime; 17 18 @ Override19 public void sessionCreated (HttpSessionEvent event) {20 System. out. println ("session creation"); 21} 22 23 @ Override24 public void sessionDestroyed (HttpSessionEvent event) {25 System. out. println ("session destruction"); 26} 27 28 @ Override29 public void attributeAdded (HttpSessionBindingEvent event) {30 System. out. println ("add attribute:" + event. getName (); 31 // when the attribute is saved, the current time is saved. 32 addTime = System. currentTimeMillis (); 33} 34 35 @ Override36 public void attributeRemoved (HttpSessionBindingEvent event) {37 System. out. println ("Remove attribute:" + event. getName (); 38 // calculate the attribute retention time when the attribute is removed. 39 long removeTime = System. currentTimeMillis (); 40 long t = (removeTime-addTime)/1000; 41 System. out. println ("data retention time:" + t + "seconds"); 42} 43 44 @ Override45 public void attributeReplaced (HttpSessionBindingEvent event) {46 System. out. println ("change attribute:" + event. getName (); 47} 48 49}
ShowUser. jsp Display User Name
1 <% @ page language = "java" contentType = "text/html; charset = UTF-8" 2 pageEncoding = "UTF-8" %> 3 <! DOCTYPE html PUBLIC "-// W3C // dtd html 4.01 Transitional // EN" http://www.w3.org/TR/html4/loose.dtd "> 4
The preparation is complete. Let's take a look at the test below:
First, enter the address in the address bar to access UserServlet. In doGet (), the user information will be saved to the session and redirected to showUser. the User name and information are displayed in jsp. You can see that the attributes and strings of the User object are displayed.
The following is the information output from the console:
Then, after a while, the console
We can see that 54 seconds later, the user property was removed, the message was not removed, and the session was not destroyed !!! Then, refresh the page and display the following information: this is a common situation ....
Then, Baidu mostly says that the session expiration time is a little longer: but it does not work.
1 <! -- Set the session expiration time (unit: minute) --> 2 <session-config> 3 <session-timeout> 30 </session-timeout> 4 </session-config>
There is another way: place a refresh. jsp file in the root directory, with the following content: the main content is 6th lines of code, refresh every second, link to yourself
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4
Add the following code to the display data page (showUser. jsp): <iframe width = 0 height = 0 src = "refresh. jsp"> </iframe>
The purpose is to constantly request the server. In my understanding, the server assumes that the client has been using this object and will not remove this data ....
In this way, although the goal has been achieved, there are a lot of drawbacks, and the cure is not a permanent cure: it is certain that the server has been requested to consume server resources, and the refreshing icon of the browser will continue to jump, it looks so uncomfortable...
**************************************** **************************************** *********************************
Finally, let's look at the solution: you only need to implement the serialization interface Serializable for the User, as shown below:
1 package com. lizhou. entity; 2 3 import java. io. serializable; 4 5/** 6 * User class 7 * @ author bojiangzhou 8 * @ date February 28, 2016 9 */10 public class User implements Serializable {11 12 private int id; 13 14 private String name; 15 16 public User () {17 18} 19 20 public User (int id, String name) {21 this. id = id; 22 this. name = name; 23} 24 25 // getter/setter Method 26 27}
The object to be saved to the session implements the serialization interface Serializable, so that the user data will be stored in the session all the time, no matter how you refresh it, unless the session is destroyed, the data will always be there !!!
So why? Below is my Baidu section:
[Object serialization allows you to convert objects that implement the Serializable interface into byte sequences, which can be fully stored for future re-generation of original objects.
For example, you can upload a string or an object, such as a socket, during network transmission. The receiver can easily parse a string. However, when an object is uploaded, the recipient does not know what object you upload after reading the byte stream, so there is no way to convert to the original object and parse the attributes of the object. serialization and deserialization are required at this time. Class to implement the serialization interface. The socket sends the byte stream of this object. After receiving the stream, the receiver can deserialize the stream into an object and then use the method and attributes of the object .]
Attached test code: session data loss test code
OK !!!