Java的对象序列化是指将那些实现了Serializable接口的对象转换成一个字符序列,并能够在以后将这个字节序列完全恢复为原来的对象。这一过程甚至可通过网络进行,这意味着序列化机制能自动弥补不同操作系统之间的差异。 只要对象实现了Serializable接口(记住,这个接口只是一个标记接口,不包含任何的方法 如果我们想要序列化一个对象,首先要创建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream(记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构)。而反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputstream、ByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。 对象序列化过程不仅仅保存单个对象,还能追踪对象内所包含的所有引用,并保存那些对象(这些对象也需实现了Serializable接口)。
要传递对象的引用属性类:
package yh.tcp.server;
import java.io.Serializable;
public class CoordObject implements Serializable{
private static final long serialVersionUID = 1L;
private double x;
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public CoordObject(double x, double y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "CoordObject [x=" + x + ", y=" + y + "]";
}
}
package yh.tcp.server;
import java.io.Serializable;
public class CoordObject implements Serializable{
private static final long serialVersionUID = 1L;
private double x;
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public CoordObject(double x, double y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "CoordObject [x=" + x + ", y=" + y + "]";
}
}
要传递的对象类型:
package yh.tcp.server;
import java.io.Serializable;
public class PersonObject implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
private CoordObject coord;
public PersonObject(String name, int age, CoordObject coord) {
super();
this.name = name;
this.age = age;
this.coord = coord;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public CoordObject getCoord() {
return coord;
}
public void setCoord(CoordObject coord) {
this.coord = coord;
}
@Override
public String toString() {
return "PersonObject [name=" + name + ", age=" + age + ", coord="
+ coord + "]";
}
}
package yh.tcp.server;
import java.io.Serializable;
public class PersonObject implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
private CoordObject coord;
public PersonObject(String name, int age, CoordObject coord) {
super();
this.name = name;
this.age = age;
this.coord = coord;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public CoordObject getCoord() {
return coord;
}
public void setCoord(CoordObject coord) {
this.coord = coord;
}
@Override
public String toString() {
return "PersonObject [name=" + name + ", age=" + age + ", coord="
+ coord + "]";
}
}
服务端:
package yh.tcp.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server = null;
Socket client = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
server = new ServerSocket(8888);
System.out.println("服务器开启,等待客户端访问……");
client = server.accept();
CoordObject coord=new CoordObject(1.1, 2.2);
PersonObject person=new PersonObject("name", 123, coord);
oos=new ObjectOutputStream(client.getOutputStream());
oos.writeObject(person);
oos.close();
client.close();
}
}
package yh.tcp.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server = null;
Socket client = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
server = new ServerSocket(8888);
System.out.println("服务器开启,等待客户端访问……");
client = server.accept();
CoordObject coord=new CoordObject(1.1, 2.2);
PersonObject person=new PersonObject("name", 123, coord);
oos=new ObjectOutputStream(client.getOutputStream());
oos.writeObject(person);
oos.close();
client.close();
}
}
客户端:
package yh.tcp.client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
Socket client = null;
ObjectInputStream ois=null;
client =new Socket("localhost",8888);
ois=new ObjectInputStream(client.getInputStream());
Object object=ois.readObject();
System.out.println(object);
ois.close();
client.close();
}
}
package yh.tcp.client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
Socket client = null;
ObjectInputStream ois=null;
client =new Socket("localhost",8888);
ois=new ObjectInputStream(client.getInputStream());
Object object=ois.readObject();
System.out.println(object);
ois.close();
client.close();
}
}
打印结果:
PersonObject [name=name, age=age, coord=CoordObject [x=1.1, y=2.2]]
以上不具备多次交互,且不支持多线程为多个客户端提供链接的机制。
下面的实例,可以让客户端对服务端序列化的对象进行操作,并且支持多个客户端同时访问。
增加线程类:
package yh.tcp.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class TcpThread implements Runnable {
private Socket client;
public Socket getClient() {
return client;
}
public void setClient(Socket client) {
this.client = client;
}
public TcpThread(Socket client) {
super();
this.client = client;
}
@Override
public void run() {
BufferedReader buf = null;
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(client.getOutputStream());
buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean flag=true;
while (flag) {
String str=buf.readLine();
if(str==null||"".equals(str)||"bye".equals(str)){
flag=false;
}else {
CoordObject coord=new CoordObject(121.1, 43.1);
PersonObject person=new PersonObject(str, 100, coord);
oos.writeObject(person);
}
}
System.out.println("当前断开一位~");
oos.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package yh.tcp.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class TcpThread implements Runnable {
private Socket client;
public Socket getClient() {
return client;
}
public void setClient(Socket client) {
this.client = client;
}
public TcpThread(Socket client) {
super();
this.client = client;
}
@Override
public void run() {
BufferedReader buf = null;
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(client.getOutputStream());
buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean flag=true;
while (flag) {
String str=buf.readLine();
if(str==null||"".equals(str)||"bye".equals(str)){
flag=false;
}else {
CoordObject coord=new CoordObject(121.1, 43.1);
PersonObject person=new PersonObject(str, 100, coord);
oos.writeObject(person);
}
}
System.out.println("当前断开一位~");
oos.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
修改服务端:
package yh.tcp.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server = null;
Socket client = null;
server = new ServerSocket(8888);
boolean flag = true;
while (flag) {
System.out.println("服务器开启,等待客户端访问……");
client = server.accept();
new Thread(new TcpThread(client)).start();
}
server.close();
}
}
package yh.tcp.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server = null;
Socket client = null;
server = new ServerSocket(8888);
boolean flag = true;
while (flag) {
System.out.println("服务器开启,等待客户端访问……");
client = server.accept();
new Thread(new TcpThread(client)).start();
}
server.close();
}
}
修改客户端:
package yh.tcp.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
Socket client = null;
ObjectInputStream ois=null;
PrintStream out=null;
BufferedReader writeInput=null;
client =new Socket("localhost",8888);
writeInput=new BufferedReader(new InputStreamReader(System.in));//键盘打印流
out=new PrintStream(client.getOutputStream());//向服务端输出流
ois=new ObjectInputStream(client.getInputStream());//从服务端接受的输入流
boolean flag=true;
while (flag) {
System.out.println("请输入信息~");
String str=writeInput.readLine();
out.println(str);
if ("".equals(str)||null==str||"bye".equals(str)) {
flag=false;
}else {
Object object=ois.readObject();
System.out.println(object);
}
}
ois.close();
client.close();
out.close();
}
}
package yh.tcp.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
Socket client = null;
ObjectInputStream ois=null;
PrintStream out=null;
BufferedReader writeInput=null;
client =new Socket("localhost",8888);
writeInput=new BufferedReader(new InputStreamReader(System.in));//键盘打印流
out=new PrintStream(client.getOutputStream());//向服务端输出流
ois=new ObjectInputStream(client.getInputStream());//从服务端接受的输入流
boolean flag=true;
while (flag) {
System.out.println("请输入信息~");
String str=writeInput.readLine();
out.println(str);
if ("".equals(str)||null==str||"bye".equals(str)) {
flag=false;
}else {
Object object=ois.readObject();
System.out.println(object);
}
}
ois.close();
client.close();
out.close();
}
}
打印结果:对于汉字的序列化反序列化也没出现乱码