Spring WebFlow继承类序列化问题:父类属性无法恢复
问题排查与解决思路
先把你给出的类B代码格式化一下,方便查看:
public class B { private Collection<Class<?>> hints = new ArrayList<>(); public B(){} public B(Collection<Class<?>> hints){ this.hints=hints; } // getter and setter for hints }
这个问题我之前在Spring WebFlow里踩过坑,核心原因大概率是序列化/反序列化环节出了问题,结合你的场景具体分析:
为什么父类B的hints状态会丢失?
Spring WebFlow在处理流程状态时,默认会把流程中的对象(比如你的表单类A)序列化后存储(通常存在HttpSession中),当需要重建对象时再执行反序列化。这里的关键问题在于:
- 你的类A实现了
Serializable接口,但父类B没有实现这个接口 - Java序列化机制有个明确规则:如果子类实现了Serializable,但父类未实现,那么父类的字段不会被纳入序列化范围。反序列化时,会调用父类的无参构造函数初始化父类部分,而你的B类无参构造正好把
hints初始化为新的空ArrayList,所以每次重建后hints都会是空集合。
怎么解决这个问题?
方案1:让父类B也实现Serializable接口
这是最直接有效的办法,修改B类的定义:
import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; public class B implements Serializable { // 建议添加序列化UID,避免后续类结构变化导致反序列化失败 private static final long serialVersionUID = 1L; private Collection<Class<?>> hints = new ArrayList<>(); public B(){} public B(Collection<Class<?>> hints){ this.hints=hints; } // getter and setter for hints }
这样Java序列化时会把父类B的hints字段一起序列化,反序列化时就能正确恢复原有状态了。
方案2:验证序列化逻辑(可选)
如果你不确定是不是序列化的问题,可以写个简单的本地测试,手动序列化/反序列化A的实例,验证hints是否能保留:
import java.io.*; public class SerializationTest { public static void main(String[] args) throws Exception { // 创建带hints的B实例,再初始化A实例 B b = new B(); b.getHints().add(String.class); A a = new A(); // 假设A是B的子类 // 序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(a); // 反序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); A restoredA = (A) ois.readObject(); // 检查hints是否存在 System.out.println(restoredA.getHints().size()); // 输出1说明正常,0说明序列化有问题 } }
方案3:检查WebFlow的序列化配置(特殊场景)
如果你的WebFlow没有使用默认的Java序列化(比如配置了JSON序列化),需要确保序列化工具能正确处理继承关系的字段:
- 比如用Jackson的话,要确认没有给
hints字段加@JsonIgnore注解 - 检查是否开启了
FAIL_ON_UNKNOWN_PROPERTIES这类严格配置,导致父类字段被忽略
内容的提问来源于stack exchange,提问作者ogarogar
相关产品推荐
相关产品推荐

