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等其他序列化方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章