前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dubbo序列化问题(三)子类覆盖父类字段hession反序列化获取不到

dubbo序列化问题(三)子类覆盖父类字段hession反序列化获取不到

作者头像
一笠风雨任生平
发布2019-08-02 11:28:00
1.1K0
发布2019-08-02 11:28:00
举报
文章被收录于专栏:服务化进程

在进行dubbo开发中遇到一个问题,当是用hession2进行序列化时,子类和父类有相同的字段时,hession2反序列化获取不到该字段数据,如下:

代码语言:javascript
复制
import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String userId;
	private String userName;
	private Date addDate;
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public Date getAddDate() {
		return addDate;
	}
	public void setAddDate(Date addDate) {
		this.addDate = addDate;
	}
	
	
}
代码语言:javascript
复制
import java.util.Date;

public class ChildrenUser extends User {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String userId;
	
	private Date addDate;

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public Date getAddDate() {
		return addDate;
	}

	public void setAddDate(Date addDate) {
		this.addDate = addDate;
	}

	@Override
	public String toString() {
		return "ChildrenUser [userId=" + userId + ", addDate=" + addDate + "]";
	}
	
}

测试程序如下:

代码语言:javascript
复制
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;

import com.alibaba.com.caucho.hessian.io.Hessian2Input;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
import com.pinganwj.clinic.api.demo.domain.ChildrenUser;
import com.pinganwj.clinic.api.demo.domain.User;


public class TestHessionLite1 {


	public static void main(String[] args) throws IOException {
		User user=new ChildrenUser();
		user.setAddDate(new Date());
		user.setUserId("123");
		user.setUserName("呵呵");
		byte[] aa=TestHessionLite1.serialize(user);
		Object mm=TestHessionLite1.deserialize(aa);
		System.out.println(mm.toString());
		
	}
	
	public static byte[] serialize(Object obj) throws IOException{  
		 ByteArrayOutputStream os = new ByteArrayOutputStream(); 
		 Hessian2Output ho = new Hessian2Output(os);  
		 byte[] cc = null;
		try {
			if(obj==null) throw new NullPointerException();  
		    ho.writeObject(obj);
		    ho.flushBuffer();
		    cc=os.toByteArray();  
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			ho.close();
		}
		return cc;  
	    
	} 
	
	public static Object deserialize(byte[] by) throws IOException{ 
		try {
			if(by==null) throw new NullPointerException();  
			ByteArrayInputStream is = new ByteArrayInputStream(by);
		    Hessian2Input hi = new Hessian2Input(is);  
		    return hi.readObject();  
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	    
	}  
}

运行该测试程序,输出如下

代码语言:javascript
复制
ChildrenUser [userId=null, addDate=null]

然后我再是用kryo来进行序列化,

代码语言:javascript
复制
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;

import org.apache.commons.codec.binary.Base64;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.JavaSerializer;
import com.pinganwj.clinic.api.demo.domain.ChildrenUser;
import com.pinganwj.clinic.api.demo.domain.User;

public class TestKryo1 {

	public static void main(String[] args) {

		User user=new ChildrenUser();
		user.setAddDate(new Date());
		user.setUserId("123");
		user.setUserName("呵呵");
		String aa=TestKryo1.serialize(user);
		Object mm=TestKryo1.deserialize(aa,User.class);
		System.out.println(mm.toString());
	}
	private static <T extends Serializable> String serialize(T obj) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.register(obj.getClass(), new JavaSerializer());
 
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        kryo.writeClassAndObject(output, obj);
        output.flush();
        output.close();
 
        byte[] b = baos.toByteArray();
        try {
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        return new String(new Base64().encode(b));
    }
 
    @SuppressWarnings("unchecked")
    private static <T extends Serializable> T deserialize(String obj,
            Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.register(clazz, new JavaSerializer());
 
        ByteArrayInputStream bais = new ByteArrayInputStream(
                new Base64().decode(obj));
        Input input = new Input(bais);
        return (T) kryo.readClassAndObject(input);
    }
}

输出结果如下:

代码语言:javascript
复制
ChildrenUser [userId=123, addDate=Fri Aug 25 00:28:45 CST 2017]

输出正确。

这个是hession2的一个坑,经过查看源码Hessian2Input类中的readObjectInstance方法

他将父类的属性都读取了

而每次第一次能读取到值,然后第二次读取就是null,都被覆盖了,所以输出都是null。

所以解决方案就是去掉子类中的字段或者父类中的字段,或者改用kryo等其他序列化方式。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档