protostuff序列化

阅读更多

    在java中,序列化是经常需要使用的,比如对象在网络中传输,那么就必须要序列化后进行传输。而java自带的序列化使用起来虽然方便,但是它序列化后占的体积大,而且不能跨语言,因此在涉及到序列化的时候必然要找到一款高效的序列化框架。在网上查找了一下,发现protostuff使用方便,而且性能比较高,本篇博客简单记录一下ptotostuff如何实现一个序列化和反序列化。

一、需求

       1、有一个用户类(Person)和一个地址类(Address),一个人有多个地址

       2、person中有部分字段不需要序列化

             |-  使用transient修饰即可不进行序列化

       3、当对地址单独序列化时,需要定制化序列化,即有用户判断在什么情况下才可以序列化。(比如:当某个字段不可为空时才可以进行序列化)

             |-  此种情况可以通过自定义Schema进行实现

       4、如果后期序列化的类中新增了字段或删除了字段如何处理,参考  这篇文章, 此处不做处理。

二、实现

1、引入pom文件

 


		
			
				io.protostuff
				protostuff-bom
				1.4.4
				pom
				import
			
		
	
	
		
			junit
			junit
			4.10
			test
		
		
			io.protostuff
			protostuff-api
		
		
			io.protostuff
			protostuff-core
		
		
			io.protostuff
			protostuff-runtime
		
		
			org.projectlombok
			lombok
			1.16.18
		
	

 注意主要是引入protostuff-core和protostuff-runtime这2个依赖

 

2、定义Address类

@Data
@Builder
public class Address {
	private String address;
	private String phone;
}

 3、自定义Address的Schema,用于定制化开发,此处简单实现,当address=null时不可进行序列化

/**
 * 自定义Address的Schema,主要是用于定制化开发
 * @描述
 * @作者 huan
 * @时间 2017年12月11日 - 下午9:57:24
 */
public class AddressSchema implements Schema
{ @Override public String getFieldName(int number) { String ret = ""; switch (number) { case 1: ret = "address"; break; case 2: ret = "phone"; default: break; } return ret; } @Override public int getFieldNumber(String name) { if ("address".equals(name)) { return 1; } else if ("phone".equals(name)) { return 2; } return 0; } @Override public boolean isInitialized(Address message) { if (null != message.getAddress()) { return true; } return false; } @Override public Address newMessage() { return Address.builder().build(); } @Override public String messageName() { return Address.class.getSimpleName(); } @Override public String messageFullName() { return Address.class.getName(); } @Override public Class typeClass() { return Address.class; } @Override public void mergeFrom(Input input, Address message) throws IOException { while (true) { int number = input.readFieldNumber(this); switch (number) { case 0: return; case 1: message.setAddress(input.readString()); break; case 2: message.setPhone(input.readString()); break; default: input.handleUnknownField(number, this); } } } @Override public void writeTo(Output output, Address message) throws IOException { if (message.getAddress() == null) { throw new UninitializedMessageException(message, this); } output.writeString(1, message.getAddress(), false); if (null != message.getPhone()) { output.writeString(2, message.getPhone(), false); } } }

 注意此处如果不了解,可以先了解一下protobuff,了解一下.proto文件的写法。

            此处做了一个简单的判断,当address==null时,不可进行序列化

4、Person类的开发

@Data
@Builder
public class Person {
	private String name;
	private Integer age;
	private transient String password;
	private List
address; }

 注意:  1、Person类包含一个Address的列表

           2、注意password字段前面有一个transient,这个表示不进行序列化

           3、@Tag注解可以用于标记字段的顺序号,但是一个类中如果要用则建议都使用

           4、上方是 官网 给出的一个警告,大致意思是:如果你想在一个非静态的内部类上使用@Tag注解,那么最好将这个非静态的内部类改成静态的内部类。
 5、编写测试代码
protostuff序列化_第1张图片

6、查看结果


protostuff序列化_第2张图片
 

 


 

  • protostuff序列化_第3张图片
  • 大小: 7.6 KB
  • protostuff序列化_第4张图片
  • 大小: 166.6 KB
  • protostuff序列化_第5张图片
  • 大小: 126.5 KB
  • 查看图片附件

你可能感兴趣的:(protostuff,序列化)