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

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

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;
	}
	
	
}
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 + "]";
	}
	
}

测试程序如下:

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

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

ChildrenUser [userId=null, addDate=null]

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

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

输出结果如下:

ChildrenUser [userId=123, addDate=Fri Aug 25 00:28:45 CST 2017]

 输出正确。

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

他将父类的属性都读取了



 

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

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

猜你喜欢

转载自lipengjavablog.iteye.com/blog/2390902