Session的序列化和反序列化

JavaWeb之Session的序列化和反序列化 && Session的活化和钝化


  • 4506

应用场景:

1.一般来说,服务器启动后,就不会再关闭了,但是如果逼不得已需要重启,而用户会话还在进行相应的操作,这时就需要使用序列化将session信息保存起来放在硬盘,服务器重启后,又重新加载。这样就保证了用户信息不会丢失,实现永久化保存

2.淘宝每年都会有定时抢购的活动,很多用户会提前登录等待,长时间不进行操作,一致保存在内存中,而到达指定时刻,几十万用户并发访问,就可能会有几十万个session,内存可能吃不消,这时就需要进行对象的活化、钝化,让其在闲置的时候离开内存,将信息保存至硬盘,等要用的时候,就重新加载进内存


一、session的序列化和反序列化

什么是序列化?

把对象的状态信息转换为可以存储或传输的形式过程,简单说就是把对象转换为字节形式存储的过程称为对象的序列化

什么是反序列化?

把字节序列转化为对象的过程


Tomcat下保存的session序列化文件

Session的序列化和反序列化_第1张图片


实现了Serializable接口的User类

[java]  view plain  copy
  1. import java.io.Serializable;  
  2.   
  3. public class User implements Serializable {  
  4.   
  5.     private static final long serialVersionUID = 1L;  
  6.     private String username;  
  7.     private String password;  
  8.     public String getUsername() {  
  9.         return username;  
  10.     }  
  11.     public void setUsername(String username) {  
  12.         this.username = username;  
  13.     }  
  14.     public String getPassword() {  
  15.         return password;  
  16.     }  
  17.     public void setPassword(String password) {  
  18.         this.password = password;  
  19.     }  
  20.     @Override  
  21.     public String toString() {  
  22.         return "User [username=" + username + ", password=" + password + "]";  
  23.     }  
  24.     public User() {  
  25.         super();  
  26.     }  
  27.     public User(String username, String password) {  
  28.         super();  
  29.         this.username = username;  
  30.         this.password = password;  
  31.     }  
  32. }  

向session中存放数据的a.jsp

[java]  view plain  copy
  1. <%@page import="cn.cil.domain.User"%>  
  2. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7. "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8.   
  9.     
  10.     "<%=basePath%>">  
  11.       
  12.     My JSP <span class="string" style="margin:0px; padding:0px; border:none; color:blue; background-color:inherit">'a.jsp'</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> starting page  
  13.       
  14.     "pragma" content="no-cache">  
  15.     "cache-control" content="no-cache">  
  16.     "expires" content="0">      
  17.     "keywords" content="keyword1,keyword2,keyword3">  
  18.     "description" content="This is my page">  
  19.   
  20.     
  21.     
  22.     
  23.     

    向 Session 存放资源

      
  24.     <%  
  25.         User user = new User("123","abc");  
  26.         session.setAttribute("user",user);  
  27.     %>  
  28.     
  29.   
  30.   
取数据的b.jsp

[java]  view plain  copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8.   
  9.     
  10.     "<%=basePath%>">  
  11.       
  12.     My JSP <span class="string" style="margin:0px; padding:0px; border:none; color:blue; background-color:inherit">'b.jsp'</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> starting page  
  13.       
  14.     "pragma" content="no-cache">  
  15.     "cache-control" content="no-cache">  
  16.     "expires" content="0">      
  17.     "keywords" content="keyword1,keyword2,keyword3">  
  18.     "description" content="This is my page">  
  19.   
  20.     
  21.     
  22.     
  23.     

    从 Seesion 中取资源

      
  24.     <%= session.getAttribute("user") %>  
  25.     
  26.   
  27.   

在向seesion保存资源后(访问a.jsp后),关闭tomcat,然后迅速打开tomcat的work目录到指定项目文件中,就会看到生成的Sessions.ser文件,这个文件保存的就是所有session对象序列化后的信息

这时,再重启Tomcat,会看到SESSIONS.ser文件消失,又被重新加载,再访问b.jsp,原来的对象信息还在


模拟对象的序列化反序列化

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileOutputStream;  
  4. import java.io.ObjectInputStream;  
  5. import java.io.ObjectOutputStream;  
  6.   
  7. import org.junit.Test;  
  8.   
  9. import cn.cil.domain.User;  
  10.   
  11.   
  12. public class TestSerializable {  
  13.   
  14.     @Test  
  15.     public void test() throws Exception {  
  16.           
  17.         User user = new User("123","abc");  
  18.         SerializeObj(user);  
  19.         User users = ObjDeSerialize();  
  20.         System.out.println(users);  
  21.     }  
  22.       
  23.     private void SerializeObj(User user) throws Exception{  
  24.           
  25.         ObjectOutputStream outObj = new ObjectOutputStream(  
  26.                 new FileOutputStream(new File("G:/SESSIONS.ser")));  
  27.         outObj.writeObject(user);  
  28.         System.out.println("对象序列化完成");  
  29.     }  
  30.       
  31.     private User ObjDeSerialize() throws Exception{  
  32.         ObjectInputStream inObj = new ObjectInputStream(new FileInputStream(  
  33.                 new File("G:/SESSIONS.ser")));  
  34.         User user = (User)inObj.readObject();  
  35.         System.out.println("对象反序列化完成");  
  36.         return user;  
  37.     }  
  38.   
  39. }  
Session的序列化和反序列化_第2张图片

特别注意:

1.进行对象的序列化和反序列化的对象,必须实现Serializable接口,否则无法进行序列化和反序列化,当然这仅仅可以进行序列化和反序列化而已,如果序列化完成的对象(已经保存至硬盘),反序列化前又修改了对象,那么反序列化会失败,所以进行序列化的对象必须还要添加serialVersionUID


[java]  view plain  copy
  1. public class User implements Serializable{   
  2.   
  3.     //private static final long serialVersionUID = 1L; //不添加ID  
  4.     private String username;  
  5.     private String password;  
  6.     //private int age = 10; 对象序列化后,新增内容  
  7.       
  8.     public String getUsername() {  
  9.         return username;  
  10.     }  
  11.     public void setUsername(String username) {  
  12.         this.username = username;  
  13.     }  
  14.     public String getPassword() {  
  15.         return password;  
  16.     }  
  17.     public void setPassword(String password) {  
  18.         this.password = password;  
  19.     }  
  20.       
  21.   
  22.       
  23.     /*@Override 
  24.     public String toString() { 
  25.         return "User [username=" + username + ", password=" + password 
  26.                 + ", age=" + age + "]"; 
  27.     }*/  
  28.       
  29.     /*@Override 
  30.     public String toString() { 
  31.         return "User [username=" + username + ", password=" + password 
  32.                 + "]"; 
  33.     }*/  
  34.     public User() {  
  35.         super();  
  36.     }  
  37.     public User(String username, String password) {  
  38.         super();  
  39.         this.username = username;  
  40.         this.password = password;  
  41.     }  
  42. }  
  43.   
  44.   
  45. @Test  
  46.     public void test2() throws Exception {  
  47.           
  48.         User user = new User("123","abc");  
  49.           
  50.         SerializeObj(user);  
  51.           
  52.     }  
  53.     @Test  
  54.     public void test3() throws Exception {  
  55.           
  56.         User users = ObjDeSerialize();  
  57.         System.out.println(users);  
  58.           
  59.     }  
  60.   

在反序列化前,打开注释部分,进行反序列化


这也就说明了,文件流中的class和web下的classpath中的class(修改后)不一致了,会抛出异常,所以进行序列化的对象,如果需要在修改后还可以进行反序列化,就必须添加serialVersionUID,如果不指定serialVersionUID,java编译器会自动帮我们添加,一个对象只要修改一点点,他们的serialVersionUID就会不一致,序列化前是一个serialVersionUID,反序列化又是一个serialVersionUID,两个serialVersionUID不一致,肯定会异常。Eclipse如此强大,不填写serialVersionUID时,它会报警。所以稍稍注意一下。

2.如果一个对象不实现Serializable接口,它是无法进行序列化的,根本就无法转换为字节序列

实现Serializable接口,就好比坐飞机的机票,有机票带你飞,没票在地上呆着

Session的序列化和反序列化_第3张图片

二、session的活化和钝化

当一个用户长时间不进行操作的时,服务器为减轻内存压力,可以将其session保存到硬盘中,等待用户再次操作的时候,再从硬盘中取出来,(保存到硬盘中的信息不会删除)

将下面配置文件放到tomcat\conf\catalina\localhost目录下!文件名称为项目名称。

[html]  view plain  copy
  1. <Context>  
  2.     <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"[如果session在1分钟内没有使用,那么Tomcat就会钝化它]>  
  3.         <Store className="org.apache.catalina.session.FileStore" directory="mysession"[把session序列化到Tomcat\work\Catalina\localhost\listener\mysession目录下。]/>  
  4.     Manager>  
  5. Context>  
当然也可以放到tomcat的config下的context.xml中,这样就是对Tomcat下所有应用都生效

Session的序列化和反序列化_第4张图片



你可能感兴趣的:(Session的序列化和反序列化)