【发布时间】:2018-01-31 08:40:19
【问题描述】:
我想以不同的时间间隔保存注入的有状态bean的数据:更改-保存-更改-保存...我正在使用核心序列化,问题是所有字节数组都是相同的。我相信代理是序列化的,因为如果我稍后反序列化其中一个数组,我会得到 bean 的当前状态。
序列化示例未捕获 bean 中的更改:
@Stateful
@RequestScoped
public class State implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
StatelessBean bean; // assume it's needed
private List<String> list = new ArrayList<>();
public void add() {
list.add("S");
}
}
这是一个 JAX-RS 类:
@Stateless
@Path("t1")
public class ChickensResource {
@Inject
State state;
@GET
@Path("/test")
public String test() {
state.add();
byte[] b0 = serialize(state);
System.out.println(b0.length + " " + Arrays.toString(b0));
state.add();
byte[] b1 = serialize(state);
System.out.println(b1.length + " " + Arrays.toString(b1)); // prints same as b0
System.out.println(b0.length + " " + Arrays.toString(b0)); // prints same thing
}
public static <T extends Serializable> byte[] serialize(T s) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos))
{
oos.writeObject(s);
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
我想要做的只是将列表保存在State 中,因为那是相关数据。我还尝试了 JSON 序列化,它给出了 IOException,但我正在尝试核心序列化。
使用 JavaEE7 和 Wildfly 10.1。
【问题讨论】:
-
您需要将
State中的bean声明更改为transient StatelessBean bean -
由于
State是@RequestScoped,ChickensResource.state中注入的东西是一个代理。这就是为什么序列化总是返回相同的东西。为什么不向State添加一个serialize()方法来处理它自己的序列化的内部并适当地处理依赖关系? -
@NikosParaskevopoulos 谢谢。这只发生在
@RequestScope上吗?我真正的State对象包含一个对象图,有些是注入的,有些不是,我什么时候需要采用您的方法?另外我read 说如果注入的bean 的代理没有被序列化,那么在反序列化它们时它将保持null。 -
@NikosParaskevopoulos 它似乎发生在任何范围内。那意味着作用域bean不能被序列化?
-
这应该发生在所有“正常范围”中:请求、会话和应用程序(+任何自定义范围)。该规范谈到了钝化,它建立在序列化之上,但完全不同。规范中没有单独提及序列化。我不会以任何方式序列化 CDI bean(Java 序列化、JSON 等)。我将代替你做的是让 CDI bean 将其状态保存在另一个不受 CDI 管理的对象中(即使用
new创建)并且是可序列化的.
标签: java jakarta-ee serialization ejb cdi