分布式通信序列化(分布式三)

序列化与反序列化

在这里插入图片描述

序列化与分布式通信关系

通过 序列化+反序列化+网络 的结合,不同的应用服务器可以共同协作起来,共同构建分布式应用
在这里插入图片描述

java中实现一个序列化与反序列化

三个步骤

  1. 实现Serializable接口
  2. 使用ObjectInputStream读
  3. 使用ObjectOutputStream 写

对应代码例子

public class Person implements Serializable{
	
	private static final long serialVersionUID = 385470237187218240L;
	
	private String name;
	private int age;

	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;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

public class SerializeDemo {

	public static void main(String[] args) throws Exception {
		// 序列化
		serializePerson();
		// 反序列化
		deSerializePerson();
	}

	private static void serializePerson() throws Exception {
		Person person = new Person();
		person.setName("张三");
		person.setAge(12);
		// System.out.println(person);
		
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
		oos.writeObject(person);
		
		System.out.println("序列化完成,文件大小为:" + new File("person.txt").length());
	}
	
	private static void deSerializePerson() throws Exception {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"));
		Person person = (Person) ois.readObject();
		System.out.println(person);
	}

}

java序列化的细节

serialVersionUID

=版本号
序列化以后,修改版本号,进行反序列化

Exception in thread "main" java.io.InvalidClassException: priv.dengjili.distributed_s1.serialize.bean.Person; local class incompatible: stream classdesc serialVersionUID = 385470237187218240, local class serialVersionUID = 85470237187218240
	at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
	at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
	at java.io.ObjectInputStream.readClassDesc(Unknown Source)
	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at priv.dengjili.distributed_s1.serialize.demo.SerializeDemo2.deSerializePerson(SerializeDemo2.java:34)
	at priv.dengjili.distributed_s1.serialize.demo.SerializeDemo2.main(SerializeDemo2.java:17)

ps: 添加会删除字段,不修改版本后,则反序列正常

静态变量的序列化

序列化并不保存静态变量的状态,因为静态变量不属于对象本身的内容

Transient关键字

transient关键字表示指定属性不参与序列化,过滤的意思

父子类问题

如果父类没有实现序列化,而子类实现列序列化。
只会序列化子类
在这里插入图片描述

序列化的存储规则

对同一个对象进行多次写入,打印出的第一次存储结果和第二次存储结果,只多了5个字节的引用关系。
并不会导致文件累加,存引用

序列化实现深度克隆

java中的深拷贝与浅拷贝:https://blog.csdn.net/dengjili/article/details/85716058

class Book implements Serializable {
	private static final long serialVersionUID = 8234484588726379017L;
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Book [name=" + name + "]";
	}
}

class Teacher implements Serializable {
	private static final long serialVersionUID = -7471815149371769182L;

	private int no;

	private Book book;

	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	@Override
	public String toString() {
		return "Teacher [no=" + no + ", book=" + book + "]";
	}

	public static void main(String[] args) throws Exception {
		// 序列化
		Book book = new Book();
		book.setName("语文");
		Teacher teacher = new Teacher();
		teacher.setNo(10001);
		teacher.setBook(book);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(teacher);

		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		// 反序列化
		ObjectInputStream ois = new ObjectInputStream(bais);
		Teacher teacher2 = (Teacher) ois.readObject();
		System.out.println(teacher == teacher2);

		System.out.println("老师1:" + teacher.getNo() + ",学科:" + teacher.getBook().getName());
		System.out.println("老师2:" + teacher2.getNo() + ",学科:" + teacher2.getBook().getName());
		
		teacher.setNo(2222);
		teacher.getBook().setName("数学");
		System.out.println("老师1:" + teacher.getNo() + ",学科:" + teacher.getBook().getName());
		System.out.println("老师2:" + teacher2.getNo() + ",学科:" + teacher2.getBook().getName());
	}
}

测试结果

false
老师1:10001,学科:语文
老师2:10001,学科:语文
老师1:2222,学科:数学
老师2:10001,学科:语文

常用序列化框架

公共依赖

		<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.13</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.54</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.baidu/jprotobuf -->
		<dependency>
			<groupId>com.baidu</groupId>
			<artifactId>jprotobuf</artifactId>
			<version>2.2.7</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.caucho/hessian -->
		<dependency>
			<groupId>com.caucho</groupId>
			<artifactId>hessian</artifactId>
			<version>4.0.51</version>
		</dependency>
bean

Person

public class Person {
	
	private String name;
	private int age;
	
	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;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

Person2

public class Person2 {
	
	@Protobuf(fieldType = FieldType.STRING, order = 1)
	private String name;
	@Protobuf(fieldType = FieldType.INT32, order = 2)
	private int age;
	
	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;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

Person3

public class Person3 implements Serializable{
	
	private static final long serialVersionUID = 3237645377924591122L;
	
	private String name;
	private int age;
	
	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;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

FastSon
public class FastSonSerialize {

	public static void main(String[] args) throws Exception {
		Person person = new Person();
		person.setName("张三");
		person.setAge(12);

		String text = JSON.toJSONString(person);
		System.out.println(text);
		System.out.println(text.getBytes().length);
		Person person2 = JSON.parseObject(text, Person.class);

		System.out.println(person == person2);
		System.out.println(person2);
	}

}

JackSon
public class JackSonSerialize {

	public static void main(String[] args) throws Exception {
		Person person = new Person();
		person.setName("张三");
		person.setAge(12);
		
		ObjectMapper mapper = new ObjectMapper();
		byte[] bytes = mapper.writeValueAsBytes(person);
		System.out.println(new String(bytes));
		System.out.println(bytes.length);
		
		Person person2 = mapper.readValue(bytes, Person.class);
		
		System.out.println(person == person2);
		System.out.println(person2);
	}

}

protobuf
/**
 * 对应github链接: https://github.com/jhunters/jprotobuf
 * 
 * @author it
 */
public class JprotobufSerialize {

	public static void main(String[] args) throws Exception {
		Codec<Person2> simpleTypeCodec = ProtobufProxy.create(Person2.class);

		Person2 person = new Person2();
		person.setName("张三");
		person.setAge(12);
		try {
			// 序列化
			byte[] bb = simpleTypeCodec.encode(person);
			System.out.println(bb.length);
			// 反序列化
			Person2 person2 = simpleTypeCodec.decode(bb);
			System.out.println(person == person2);
			System.out.println(person2);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

Hessian
public class HessianSerialize {

	public static void main(String[] args) throws Exception {
		Person3 Person = new Person3();
		Person.setName("张三");
		Person.setAge(12);
		
		ByteArrayOutputStream buffers = new ByteArrayOutputStream();
		HessianOutput output = new HessianOutput(buffers);
		
		output.writeObject(Person);
		
		byte[] byteArray = buffers.toByteArray();
		System.out.println(byteArray.length);
		HessianInput input = new HessianInput(new ByteArrayInputStream(byteArray));
		Person3 person2 = (Person3) input.readObject(Person3.class);
		
		System.out.println(Person == person2);
		System.out.println(person2);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值