在進行dubbo開發中遇到一個問題,當是用hession2進行序列化時,子類和父類有相同的字段時,hession2反序列化獲取不到該字段數據,以下:java
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 + "]"; } }
測試程序以下:apache
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; } }
運行該測試程序,輸出以下api
ChildrenUser [userId=null, addDate=null]
而後我再是用kryo來進行序列化,dom
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); } }
輸出結果以下:ide
ChildrenUser [userId=123, addDate=Fri Aug 25 00:28:45 CST 2017]
輸出正確。測試
這個是hession2的一個坑,通過查看源碼Hessian2Input類中的readObjectInstance方法this
他將父類的屬性都讀取了code
而每次第一次能讀取到值,而後第二次讀取就是null,都被覆蓋了,因此輸出都是null。blog
因此解決方案就是去掉子類中的字段或者父類中的字段,或者改用kryo等其餘序列化方式。開發