• 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】

  • 相关阅读:
    jq使用手册
    MVC4 Forms 验证,部署到Hyper-v上.FormsAuthentication.SetAuthCookie无效的问题
    ASP.NET FormsAuthentication跨站点登录时绝对地址返回的问题
    FireBird.conf 常用参数说明 (FrieBird3.0.4版)
    AnkhSVN2019
    控制台程序的RedirectStandardOutput
    代替webbrowser的插件:CefSharp
    mssql分区视图
    Firebird写存储过程
    .net项目多个目标架构
  • 原文地址:https://www.cnblogs.com/qdhxhz/p/7993984.html
Copyright © 2020-2023  润新知