java提高(6)---Serializable

Serializable--初解

一 序列化是干什么的?

          我们知道,在jvm中引用数据类型存在于栈中,而new创建出的对象存在于堆中。如果电脑断电那么存在于内存中的对象就会丢失。那么有没有方法将对象保存到磁盘(对象持久化存储)或通过网络传输到远处的其他地方呢?

         答案是可以,但是我们必须要求所有支持持久化存储的类实现Serializable接口。Serializable就像个通行证,只有持有这个通行证,jvm才让类创建的对象进行持久化。这个接口将类与一个称为serialVersionUID的变量关联起来,这个serialVersionUID就是在反序列化中用来确定由哪个类来加载这个对象。

二、什么情况下需要序列化   
    a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
    b)当你想用套接字在网络上传送对象的时候;
    c)当你想通过RMI传输对象的时候;

三、JavaBean为什么要实现java.io.Serializable接口实现序列化?

        找了个比较好理解的例子:客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。

       web服务器通常将那些暂时不活动但未超时的HttpSession对象转移到文件系统或数据库中保存,服务器要使用他们时再将他们从文件系统或数据库中装载入内存,这种技术称为Session的持久化。

      将HttpSession对象保存到文件系统或数据库中,需要采用序列化的方式将HttpSession对象中的每个属性对象保存到文件系统或数据库中;将HttpSession对象从文件系统或数据库中装载如内存时,需要采用反序列化的方式,恢复HttpSession对象中的每个属性对象。所以存储在HttpSession对象中的每个属性对象必须实现Serializable接口。当然如果不是存储在session中的JavaBean可以不用存储哈。

举个简单例子:

     Student

import java.io.Serializable;  
public class Student implements Serializable {  
    /*serialVersionUID来决定由哪个类来加载存在于文件中的对象 
     * 如果指定serialVersionUID的数值,那就能使得其不再与类的成员变量相关联 
     * 不然你已经把对象保存到数据库,这个时候你再给这个对象新增属性,那么反序列化 
     * 就会报:本地类不匹配的错误,但如果指定serialVersionUID值那就不会报错。 
     */   
     private static final long serialVersionUID = -5182532647273106745L;   
      
     //成员变量写成static的话是不能被持久化的    
    public static  String countryName="china";  
        private String name;    
        private int age;    
        //如果想对非静态的数据也不想序列化,则需要加入关键字    
       transient String sex;   
       /* 提供set和get方法,无参和有参方法*/   
}  

   测试类

 1 import java.io.*;  
 2 public class SerializableTest {   
 3     public static void main(String[] args) {    
 4             writeObj();    
 5             readObj();    
 6         }    
 7         public static  void writeObj()    
 8         {    
 9             Student student=new Student("小筱", 1, "女");       
10             try {    
11                 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\student.txt"));    
12                 oos.writeObject(student);    
13                 oos.close();    
14             } catch (IOException e) {    
15                 e.printStackTrace();    
16             }    
17         }    
18         public  static  void  readObj()    
19         {    
20             try {    
21                 ObjectInputStream ooi=new ObjectInputStream(new FileInputStream("d:\\student.txt"));    
22                 try {    
23                     Object obj=ooi.readObject();    
24                     Student student=(Student)obj;     
25                     System.out.println("age:"+student.getAge()+",name:"+student.getName()+",countryName:"+student.countryName+",sex:"+student.getSex());    
26                 } catch (ClassNotFoundException e) {    
27                     e.printStackTrace();    
28                 }    
29                 ooi.close();    
30             } catch (IOException e) {    
31                 e.printStackTrace();    
32             }    
33         }    
34 }  

第二个小例子我没有亲自测试:用套接字在网络上传送对象

 1.首先建立要传输的对象 

 1 //建立用来持续化的对象    
 2 import java.io.Serializable;    
 3 public class ObjectSeri implements Serializable{    
 4         
 5     //成员变量写成static的话是不能被持久化的    
 6     //private关键字是不能被持久化的,脱离了JVM,成员变量是不在JVM的安全机制之内    
 7     private String name;    
 8     private String age;    
 9     /*set和get方法*/ <span style="color:#333333;"><strong>   
10   </strong></span>  

 2.有了传输的对象,下一步就是建立一个服务端线程来监听socket端口,并且在run方法里面实现读取对象的数据

 1 import java.io.IOException;    
 2     import java.io.ObjectInputStream;    
 3     import java.net.ServerSocket;    
 4     import java.net.Socket;      
 5 //serverTest类继承thread类,监听端口来的信息    
 6 public class serverTest extends Thread {    
 7 //  private final String serverIP = "127.0.0.1";    
 8     private final int serverPort = 3400;    
 9     private ServerSocket server;    
10     public serverTest() {    
11         try {    
12             // ServerSocket server=new ServerSocket(serverPort);    
13             server = new ServerSocket(serverPort);    
14             System.out.println("正在监听3400端口");    
15         } catch (IOException e) {    
16             e.printStackTrace();    
17         }    
18     }    
19     public void run() {    
20         Socket socket = null;    
21         ObjectInputStream in;    
22         while (true) {    
23             try {    
24                 synchronized (server) {    
25                     socket = server.accept();    
26                 }    
27                 System.out.println("当前的连接是:"    
28                         + socket.getInetAddress().toString());    
29                 socket.setSoTimeout(20000);    
30                 in = new ObjectInputStream(socket.getInputStream());    
31                 ObjectSeri data = (ObjectSeri) in.readObject();    
32                 System.out.println("The name is:" + data.getName()    
33                         + "and age is:" + data.getAge());    
34                 in.close();    
35                 in = null;    
36                 socket.close();    
37             } catch (IOException | ClassNotFoundException e) {    
38                 e.printStackTrace();    
39             }    
40         }    
41     }      
42      public static void main(String args[]) {    
43           (new serverTest()).start();    
44          }    

3.最后,建立一个客户端来测试下

 1 import java.io.ObjectOutputStream;    
 2     import java.net.InetSocketAddress;    
 3     import java.net.Socket;     
 4 //建立一个client测试类    
 5 public class TestClient {    
 6     private String address = "127.0.0.1";    
 7     private int port = 3400;    
 8     
 9     public TestClient() {    
10         // Prepare the data need to transmit    
11         ObjectSeri data = new ObjectSeri();    
12         data.setName("Scott");    
13         data.setAge("34");    
14         Socket client = new Socket();    
15         InetSocketAddress adr = new InetSocketAddress(this.address, this.port);    
16         try {    
17             client.connect(adr, 10000);    
18             ObjectOutputStream out = new ObjectOutputStream(    
19                     client.getOutputStream());    
20             // send object    
21             out.writeObject(data);    
22             out.flush();    
23             out.close();    
24             out = null;    
25             data = null;    
26             client.close();    
27             client = null;    
28         } catch (java.io.IOException e) {    
29     
30             System.out.println("IOException :" + e.toString());    
31         }    
32     }    
33     public static void main(String[] args) {    
34         new TestClient();     
35     }      
36 } <span style="color: rgb(51, 51, 51);"> </span>  

 输出结果如下:

正在监听3400端口
当前的连接是:/127.0.0.1
The name is:Scottand age is:34

 

今天:2017:12:05 发现自己用到了,就是jquery表单提交,用post提交,这样有个最大的好处,就是我不用一个值一个值提交,而是把表单提交过去      

$.post('your url', $("form").serialize(), function(data) {  
        // your code  
    }  
});  

 

    小筱的窝:水滴石穿,成功的速度一定要超过父母老去的速度! 少尉【2】

 

 

posted on 2017-12-06 17:44  雨点的名字  阅读(890)  评论(0编辑  收藏  举报