防止应用程序某些部分的组件树序列化

Tuu*_*nen 1 jsf serialization jsf-2

是否可以明确拒绝 JSF 序列化某些组件树?目前我正在将一个不可序列化的对象传递给<h:inputText>

<h:inputText value="#{nonSerializableBean.nonSerializableClassInstance}" />
Run Code Online (Sandbox Code Playgroud)

单击几次后会发生什么(在视图恢复期间):

javax.faces.FacesException: Unexpected error restoring state for component
with id configurationForm:j_idt292:j_idt302:field.  Cause:
java.lang.IllegalStateException: java.lang.InstantiationException:
my.namespace.NonSerializableClass
Run Code Online (Sandbox Code Playgroud)

我认为发生这种情况是因为 JSF 无法恢复nonSerializableClassInstance

Caused by: java.lang.IllegalStateException: java.lang.InstantiationException: com.foobar.utils.text.Period
at javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:110)
at javax.faces.component.ComponentStateHelper.restoreState(ComponentStateHelper.java:292)
at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1444)
at javax.faces.component.UIOutput.restoreState(UIOutput.java:255)
at javax.faces.component.UIInput.restoreState(UIInput.java:1359)
Run Code Online (Sandbox Code Playgroud)

一个额外的问题:不让支持 bean 可序列化可以吗?那么这是否应该阻止这些序列化/反序列化?

一些背景:

我们有很多 3rd 方类,需要在 JSF 中提供表单。问题是我们不能直接在 JSF 页面上使用这些类,因为它们没有实现 Serialized 接口,因此如果 JSF 运行时决定序列化/反序列化页面和组件树,它们将会/应该失败。这些类是“封闭的”,我们不允许修改它们。

运行 Mojarra 2.0.2。

Bal*_*usC 5

Javabean 按照规范应该实现Serializable. JSF 只是遵循/遵守此规范。

这些类是“封闭的”,我们不允许修改它们。

最好的选择是将其包装为transient一个类的属性,该类实现Serializable并相应地实现writeObject()readObject()

public class SerializableClass implements Serializable {

    private transient NonSerializableClass nonSerializableClass;

    public SerializableClass(NonSerializableClass nonSerializableClass) {
        this.nonSerializableClass = nonSerializableClass;
    }

    public NonSerializableClass getNonSerializableClass() {
        return nonSerializableClass;
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(nonSerializableClass.getProperty1());
        oos.writeObject(nonSerializableClass.getProperty2());
        // ...
    }

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        nonSerializableClass = new NonSerializableClass();
        nonSerializableClass.setProperty1((String) ois.readObject());
        nonSerializableClass.setProperty2((String) ois.readObject());
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

最后使用该类来代替。您最终可以让它extends NonSerializableClass通过一个像样的 IDE 自动生成委托方法。

不管怎样,它只会有很多不透明和样板代码,但由于不允许修改这些类......(我个人会推动第 3 方的东西让它们所谓的 Javabean 来实现Serializable因为正是他们违反了标准/规范)。