赞
踩
- <!--hessian-->
- <dependency>
- <groupId>com.caucho</groupId>
- <artifactId>hessian</artifactId>
- <version>4.0.38</version>
- </dependency>
- public class HessianSerializerUtil {
-
- public static <T> byte[] serialize(T obj) {
- byte[] bytes = null;
- // 1、创建字节输出流
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- // 2、对字节数组流进行再次封装
-
- // step 1. 定义外部序列化工厂
- //ExtSerializerFactory extSerializerFactory = new ExtSerializerFactory();
- //extSerializerFactory.addSerializer(java.time.OffsetDateTime.class, new OffsetDateTimeRedisSerializer());
- //extSerializerFactory.addDeserializer(java.time.OffsetDateTime.class, new OffsetDateTimeRedisDeserializer());
- // step 2. 序列化工厂
- //SerializerFactory serializerFactory = new SerializerFactory();
- //serializerFactory.addFactory(extSerializerFactory);
-
- HessianOutput hessianOutput = new HessianOutput(bos);
- //hessianOutput.setSerializerFactory(serializerFactory);
-
- try {
- // 注意,obj 必须实现Serializable接口
- hessianOutput.writeObject(obj);
- bytes = bos.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return bytes;
- }
-
- public static <T> T deserialize(byte[] data) {
- if (data == null) {
- return null;
- }
- // 1、将字节数组转换成字节输入流
- ByteArrayInputStream bis = new ByteArrayInputStream(data);
-
- // step 1. 定义外部序列化工厂
- //ExtSerializerFactory extSerializerFactory = new ExtSerializerFactory();
- //extSerializerFactory.addSerializer(java.time.OffsetDateTime.class, new OffsetDateTimeRedisSerializer());
- //extSerializerFactory.addDeserializer(java.time.OffsetDateTime.class, new OffsetDateTimeRedisDeserializer());
- // step 2. 序列化工厂
- //SerializerFactory serializerFactory = new SerializerFactory();
- //serializerFactory.addFactory(extSerializerFactory);
- HessianInput hessianInput = new HessianInput(bis);
- //hessianInput.setSerializerFactory(serializerFactory);
- Object object = null;
-
- try {
- object = hessianInput.readObject();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return (T) object;
- }
- }

- package cn.micai.base.io;
-
- import java.io.Serializable;
-
- /**
- * 描述:
- * <p>
- *
- * transient使用小结
- * 1.一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
- * 2.transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
- * 3.被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
- *
- * @author: 赵新国
- * @date: 2018/6/7 12:10
- */
- public class Employee implements Serializable {
-
- private static final long serialVersionUID = 1L;
- private int employeeId;
- private String employeeName;
- /**
- * 使用transient关键字,表示该字段不序列化
- */
- private transient String department;
-
- public int getEmployeeId() {
- return employeeId;
- }
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
- public String getEmployeeName() {
- return employeeName;
- }
- public void setEmployeeName(String employeeName) {
- this.employeeName = employeeName;
- }
- public String getDepartment() {
- return department;
- }
- public void setDepartment(String department) {
- this.department = department;
- }
-
- @Override
- public String toString() {
- return "Employee{" +
- "employeeId=" + employeeId +
- ", employeeName='" + employeeName + '\'' +
- ", department='" + department + '\'' +
- '}';
- }
- }

- public class Person implements Serializable {
- private static final long serialVersionUID = 2l;
- private int gender;
-
- public int getGender() {
- return gender;
- }
-
- public void setGender(int gender) {
- this.gender = gender;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "gender='" + gender + '\'' +
- '}';
- }
- }
-
- public class Em extends Person {
-
- private int gender;
-
- public Em() {
- }
-
- @Override
- public int getGender() {
- return gender;
- }
-
- @Override
- public void setGender(int gender) {
- this.gender = gender;
- //super.setGender(gender);
- }
-
- @Override
- public String toString() {
- return "Em{" +
- "gender=" + gender +
- '}';
- }
- }
-
-
-
- 测试类:
- public class Set {
-
- public static void main(String[] args) throws Exception{
-
- Em person=new Em();
- person.setGender(1);
-
-
- FileOutputStream fos = new FileOutputStream("tempdata.ser");
- Hessian2Output output = new Hessian2Output(fos);
- output.writeObject(person);
- output.close();
-
-
- FileInputStream fis = new FileInputStream("tempdata.ser");
- Hessian2Input input = new Hessian2Input(fis);
-
-
- Em p = (Em) input.readObject();
- System.out.println(p);
-
-
-
-
-
- }
- }
-
- 输出结果为:
- Em{gender=0}

理论上输出的结果应该为“gender=1”,但现在为gender=0,原因如下:
- hessian序列化的时候会取出对象的所有自定义属性,相同类型的属性是子类在前父类在后的顺序;
- hessian在反序列化的时候,是将对象所有属性取出来,存放在一个map中 key = 属性名 value是反序列类,相同名字的会以子类为准进行反序列化;
- 相同名字的属性 在反序列化的是时候,由于子类在父类前面,子类的属性总是会被父类的覆盖,由于java多态属性,在上述例子中父类 student.name = null。
得出结论,两种解决办法
1 使用hessian序列化时,一定要注意子类和父类不能有同名字段
2 在给子类赋值的时候,也给父类赋值。
@Override
public void setGender(int gender) {
this.gender = gender;
//super.setGender(gender);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。